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へ渡す。
Model21は1〜20の範囲外なのでIllegalArgumentExceptionで通知する。計算結果は作らない。
ServletからJSPQuoteServletが例外を受け取り、エラーと入力値を属性に入れて入力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の後のreturndoPostを終了し、エラー画面の表示後に変換や計算が続かないようにするため。

showError内のforwardが終わると、呼び出し元のdoPostへ制御が戻ります。そこでreturnして後続を止めます。また、「入力チェックでエラーになった文字列だから表示しても安全」とは限らないため、再表示でもエスケープを行います。

元の記事に戻る

JavaのWebアプリで入力チェックはどこに書く?HTML・Servlet・Modelの役割分担