【SpringMVC】バリデーションチェック

SpringMVCでバリデーションチェックを実施します。
例として、作業時間入力用のクラスがあるとして、それを複数所持するListがあるとし、
JSPでそのListをループし、作業時間入力レコードを複数表示およびチェックします。

  • バリデーションチェックのjarファイル追加
    「【SpringMVC設定】ファイルその4」を参考にpom.xmlにjarファイルを追加する。
  • アノテーション追加
    作業時間入力用のクラスは全て必須項目とするため、「@NotNull」を追加する。

    public class DayTimeWork implements Serializable {
        private static final long serialVersionUID = 1L;
    
        @NotNull
        private String ankenNo;
        @NotNull
        private String startTime;
        @NotNull
        private String endTime;
    
        アクセサメソッドは省略。
    }
    

    作業時間入力用のクラスを保持するListには「@Valid」を追加する。
    「@Valid」はネストしたクラスも検証対象とする場合、追加します。

    public class DayTime implements Serializable {
        @Valid
        private List<DayTimeWork> dayTimeWork;
    
        アクセサメソッドは省略。
    }
    
  • コントローラーへの設定追加
    Javaコントローラーにバリデーションチェックを実施するための設定を追加する。
    「@Validated」の次の項目にBindingResultを記載しないと
    実行時にValidationExceptionが発生する。

    
    @Controller
    public class InputController {
    
        @InitBinder
        public void initBinder(WebDataBinder binder) {
            // bind empty strings as null
            binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
        }
    
        @RequestMapping(value = "/updateDayTime", method = RequestMethod.POST)
        public String updateDayTime(
                @ModelAttribute(value = "dayTime") DayTime dayTime, 
                final @Validated DayTime inputDayTime, 
                BindingResult result, 
                Model model) {
            // 処理省略
        }
    }
    
  • JSPへの設定追加
    JSPでバリデーションチェック結果を取得する。
    Thymeleafのタグを利用し、全項目内でエラーが1つでもあれば、
    変数errとしてエラーを取得し、表示しています。

    <form class="form-horizontal" action="#" th:action="@{/updateDayTime}" th:object="${dayTime}" method="post">
    <fieldset>
      <ul th:if="${#fields.hasErrors('*')}">
        <li th:each="err : ${#fields.errors('*')}" th:text="${err}">Input is incorrect</li>
      </ul>
    </fieldset>
    </form>
    

    Thymeleafのタグを利用し、エラー項目のテキストボックスの枠を赤くしたり、
    入力がない場合、placeholderで「案件番号」という文字を初期表示することも可能。

    <form class="form-horizontal" action="#" th:action="@{/updateDayTime}" th:object="${dayTime}" method="post">
      <table class="table">
        <!-- 処理省略 -->
        <tr th:each="vc, row : *{dayTimeWork}" >
          <td th:class="${#fields.hasErrors('dayTimeWork[__${row.index}__].ankenNo')}? has-error"  align="center">
          <input type="text" th:field="*{dayTimeWork[__${row.index}__].ankenNo}" placeholder="案件番号" class="form-control" />
          </td>
        </tr>
      </table>
    </form>