JavaのWebアプリで入力チェックはどこに書く?HTML・Servlet・Modelの役割分担|確認問題の回答例
JavaのWebアプリで入力チェックはどこに書く?HTML・Servlet・Modelの役割分担の確認問題の回答例です。HTML・Servlet・Model・JSPのどこが何を担当するかを確認します。
問題1:HTMLを通らない送信にも備える
HTMLのrequiredやpatternは、通常のブラウザ操作で入力ミスに気付くためのものです。HTMLを書き換えたり、HTTPクライアントから直接送信したりすると、ブラウザのチェックを通らない値が届きます。Servletでも受け取った文字列を確認します。
curl -i --data-urlencode 'quantity=abc' \
http://localhost:8080/lesson06/quote
この例では400と「数量は半角数字で入力してください。」を期待します。JSPの入力欄にabcが残ることも確認します。ブラウザがabcを送信前に止めた、という結果だけではサーバー側のチェックは検証できません。
問題2:整数にできても、業務ルールでは範囲外
| 担当 | 数量21の扱い |
|---|---|
| HTML | 空ではなく半角数字なので、この記事のrequired・patternを通過する。 |
| Servlet | 文字列”21″をintの21へ変換し、Modelへ渡す。 |
| Model | 21は1〜20の範囲外なのでIllegalArgumentExceptionで通知する。計算結果は作らない。 |
| ServletからJSP | QuoteServletが例外を受け取り、エラーと入力値を属性に入れて入力JSPへforwardする。 |
Modelが直接JSPへ戻すわけではありません。画面へ進めるのはServlet、入力値と案内をHTMLにするのはJSPです。結果として入力欄の21と「数量は1〜20で指定してください。」が表示されます。
問題3:リダイレクト先は新しいリクエスト
sendRedirectでは、ブラウザが移動先へ新しいリクエストを送ります。元のリクエストに設定したquantityTextとerrorは、自動では引き継がれません。今回の構成なら、属性を設定した同じリクエストでforwardします。
request.setAttribute("error", message);
request.getRequestDispatcher("/quote-form.jsp")
.forward(request, response);
quantityTextはdoPostの初めに保存済みです。上の処理はshowErrorの中の抜粋で、HTTPステータスの設定は本文のコードにあります。showErrorを呼んだdoPost側ではreturnも行います。リダイレクト自体が使えないわけではなく、使うなら別のデータ受け渡し設計が必要です。
問題4:元の値、安全な表示、処理の停止を分ける
| コード | 目的 |
|---|---|
| quantityText属性 | 変換前の文字列abcを残し、入力欄へ戻すため。 |
| Html.escape() | 入力値をHTMLの命令ではなく文字として表示するため。abc自体は変わらないが、引用符や<などを含む入力にも備える。 |
| showErrorの後のreturn | doPostを終了し、エラー画面の表示後に変換や計算が続かないようにするため。 |
showError内のforwardが終わると、呼び出し元のdoPostへ制御が戻ります。そこでreturnして後続を止めます。また、「入力チェックでエラーになった文字列だから表示しても安全」とは限らないため、再表示でもエスケープを行います。