アイキャッチ

実装・エラー解決

SpringMVCのBindingResultは順序が大事だった話

この記事は、Spring MVCでFormの後にBindingResultを追加したとき、引数の順序で400応答になった記録です。BindingResultの置き方と、入力エラー時の画面表示・テストを一通り確認したい場合は、BindingResultの使い方と注意点へ進んでください。ここでは当時の失敗例と調査の経緯を残しています。
関連記事BindingResultの使い方と注意点|@Validの直後に置く理由 BindingResult は、 @Valid で検出した入力エラーをControllerで受け取るための引数です。重要なのは、 @Valid を付けたFormの直後に置くことです。 記事を読む
フォームの入力エラーをController内で扱うため、BindingResult を追加しました。bindingResult.hasErrors() は、その結果にエラーがあるかを判定するメソッドです。当時は次の引数順で追加していました。  
public String acceptInquiry(@ModelAttribute @Valid UserInquiryForm c06_userInquiryNewForm, Model model,BindingResult bindingResult)
引数の順番が、Form/Model/BindingResultとなっています。 後から追加したBindingResultが最後に追加されています。 この引数順でリクエストを送ったところ、当時のTomcat 8.5.13では次のHTTP 400の画面が返りました。
HTTPステータス 400 - Bad Request Type ステータスレポート 説明 The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing). Apache Tomcat/8.5.13  
この画面にはTomcatのバージョンとHTTP 400が出ています。Spring MVCの例外型までは、このときの記録から特定できません。   なぜなのか。 調べていくと同じような話が質問されていました。 https://stackoverflow.com/questions/29432717/spring-mvc-validation-status-400   修正は、引数を Form → BindingResult → Model の順にすることです。BindingResult をForm引数の直後に置くと、Spring MVCがそのFormの入力エラーをControllerへ渡します。   現在のSpring MVCのルールは公式リファレンスのModelAttributeに記載されています。順序を比べた現行の実行例は、冒頭の関連記事から確認できます。   Springを使っていて、BindingResultを使うときは順番に気を付けましょう。

-実装・エラー解決
-,