[[FrontPage]] > [[Spring Bootの覚書]]
#contents
* 入力チェック [#x01c1898]
以下のような画面を考える。~
~
#ref(sbvd-page1.png)
#ref(./sbvd-page1.png,wrap,nolink,サンプル画面)
- 名前は必須で5文字以下とする。
- 年齢は0以上の整数とする。
- 入力にエラーがある場合は入力域の背景色を赤にし、横にエラーメッセージを表示する。
** 1. 画面の作成(Thymeleaf) [#b7ecdfba]
- 画面を作成する。~
~
(src/main/resources/templates/validSample.html)
#sh(html){{
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link th:href="@{/resources/css/base.css}" rel="stylesheet" type="text/css" />
<title>validation Sample</title>
</head>
<body>
  <a th:href="@{/}">Topページ</a>
  <hr />
  <form th:action="@{/validSample}" th:object="${form}" method="post">
    <table>
      <tr>
        <td>名前:</td>
        <td>
          <input type="text" th:field="*{name}" th:errorclass="fieldError" />
        </td>
        <td th:if="${#fields.hasErrors('name')}" th:errors="*{name}"
          style="color: red"></td>
      </tr>
      <tr>
        <td>年齢:</td>
        <td>
          <input type="text" th:field="*{age}" th:errorclass="fieldError" />
        </td>
        <td th:if="${#fields.hasErrors('age')}" th:errors="*{age}"
          style="color: red"></td>
      </tr>
    </table>
    <input type="submit" value="送信" />
  </form>
</body>
</html>
}}
~
(src/main/resources/static/resources/css/base.css抜粋)
#sh(css){{
.fieldError {
  background-color: #ff8080;
}
}}
** 2. フォームクラスの作成 [#w3685eaa]
- 入力値を保持するBeanクラスを作成し、各フィードに検証用のアノテーションを記述する。~
~
(src/main/java/com/ziqoo/sbSample/web/form/ValidSampleForm.java抜粋)
#sh(java){{
public class ValidSampleForm {
    @NotBlank
    @Size(max=5)
    private String name;

    @Pattern(regexp="[0-9]*")
    private String age;
}}
** 3. コントローラクラスの作成 [#j17c4ac0]
- 入力の検証を行う引数に対して@Validを付与する。検証結果は引数のBindingResultで受け取る。~
dispValidSampleメソッドは初期表示用で、入力チェックは不要のため、@Validは付与しない。~
以下の例では発生したエラーコードをログに出力している。~
~
(src/main/java/com/ziqoo/sbSample/web/ValidSampleContrller.java)
#sh(java){{
package com.ziqoo.sbSample.web;

import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.ziqoo.sbSample.web.form.ValidSampleForm;

@Controller
public class ValidSampleContrller {
    private static final Logger log = LoggerFactory
.getLogger(ValidSampleContrller.class);

    @RequestMapping(value="/validSample", method = RequestMethod.GET)
    public String dispValidSample(@ModelAttribute("form") ValidSampleForm form, Model model) {
        return "validSample";
    }

    @RequestMapping(value="/validSample", method = RequestMethod.POST)
    public String postValidSample(@ModelAttribute("form") @Valid ValidSampleForm form, BindingResult result, Model model) {

        if (result.hasErrors()) {
            for(FieldError err: result.getFieldErrors()) {
                log.debug("error code = [" + err.getCode() + "]");
            }
        }
        return "validSample";
    }
}
}}
- 実行すると以下のようになる。~
~
#ref(sbvd-page2.png)
#ref(./sbvd-page2.png,wrap,nolink,結果)

** 4. エラーメッセージの一覧表示 [#o64258c2]
エラーメッセージをページ先頭にまとめて表示してみる。
- htmlを修正する。~
~
(src/main/resources/templates/validSample.html抜粋)
#sh(html){{
<body>
  <a th:href="@{/}">Topページ</a>
  <hr />
  <form th:action="@{/validSample}" th:object="${form}" method="post">
    <ul>
      <li th:each="e : ${#fields.detailedErrors()}"
        th:class="${e.global}? globalerrMsg : fielderrMsg" th:text="${e.message}" />
    </ul>
    <table>
      <tr>
        <td>名前:</td>
        <td>
        <input type="text" th:field="*{name}"
          th:errorclass="fieldError" />
        </td>
      </tr>
}}
~
(src/main/resources/static/resources/css/base.css抜粋)
#sh(css){{
.fielderrMsg {
  color: red;
}
.globalerrMsg {
  color: blue;
}
}}
- 実行結果~
~
#ref(./sbvd-page3.png,wrap,nolink,結果)
** 5. エラーメッセージの変更 [#k84f8304]
- ライブラリーにある、hibernate-validator-xxx.jar内のorg.hibernate.validator.ValidationMessages.propertiesをsrc/main/resourcesにコピーし、
メッセージを編集する。 ~
メッセージにフィールド名も表示させるため、メッセージ内に{0}を記述する。~
~
(src/main/resources/ValidationMessages.properties抜粋)
#sh(){{
javax.validation.constraints.Pattern.message     = {0}:入力は "{regexp}"にマッチする文字列を入力してください。
javax.validation.constraints.Size.message        = {0}:{min}文字以上 {max}文字以下で入力してください。
・・・
org.hibernate.validator.constraints.NotBlank.message                = {0}:入力は必須です。
}}
- 実行結果~
~
#ref(./sbvd-page4.png,wrap,nolink,結果)

- 表示されるフィールド名を変更する~
メッセージソースに指定されているメッセージファイルに~
"フィールド名=表示名称"を記述する。~
~
(src/main/resources/i18n/messages_ja.properties抜粋)
#sh(){{
name=名前
age=年齢
}}
- 実行結果~
~
#ref(./sbvd-page5.png,wrap,nolink,結果)

** 6. 型変換時エラーのメッセージ指定 [#je869f84]
- フォームクラスのageフィールドをInteger型に変更し、ValidationMessages.propertiesを編集する。~
~
(src/main/java/com/ziqoo/sbSample/web/form/ValidSampleForm.java抜粋)~
#sh(java){{
    @Min(0)
    private Integer age;
}}
~
(src/main/resources/ValidationMessages.properties抜粋)~
#sh(){{
javax.validation.constraints.Min.message         = {0}:{value}以上の数値を入力してください。
}}
~
- ここで、年齢に数値以外を入力すると以下のようになる。~
~
#ref(./sbvd-page6.png,wrap,nolink,結果)
~
- この場合のエラーメッセージを指定するために、メッセージファイルへ~
"エラーコード=メッセージ"を記述する。~
(エラーコードはコントローラから表示されるログを参照)~
~
(src/main/resources/i18n/messages_ja.properties抜粋)
#sh(){{
typeMismatch={0}:入力された文字はタイプが違います。
}}
- 実行結果~
~
#ref(./sbvd-page7.png,wrap,nolink,結果)
~
- 変換先のタイプによりメッセージを変える場合~
~
(src/main/resources/i18n/messages_ja.properties抜粋)
#sh(){{
typeMismatch={0}:入力された文字はタイプが違います。
typeMismatch.java.lang.Integer={0}:整数を入力してください。
}}

- フィールド固有のメッセージを指定する場合~
~
(src/main/resources/i18n/messages_ja.properties抜粋)
#sh(){{
typeMismatch={0}:入力された文字はタイプが違います。
typeMismatch.java.lang.Integer={0}:整数を入力してください。
typeMismatch.age=年齢として有効な数値を入力してください。
}}
- 実行結果~
~
#ref(./sbvd-page8.png,wrap,nolink,結果)

** 7. 日付のフォーマット指定 [#a1ae7818]
- application.propertiesへ日付のフォーマットを記述する。~
~
(src/main/resources/application.properties抜粋)
#sh(){{
spring.mvc.date-format=yyyy/MM/dd
}}
- 画面、フォームクラスに日付フィールドを追加し、メッセージファイルにエラーメッセージを追加する。~
~
(src/main/resources/templates/validSample.html抜粋)~
#sh(html){{
       <tr>
        <td>誕生日:</td>
        <td>
        <input type="text" th:field="*{birthday}"
          th:errorclass="fieldError" />
        </td>
      </tr>
    </table>
}}
~
(src/main/java/com/ziqoo/sbSample/web/form/ValidSampleForm.java抜粋)~
#sh(java){{
    private Date birthday;
}}
~
(src/main/resources/i18n/messages_ja.properties抜粋) 
#sh(){{
typeMismatch={0}:入力された文字はタイプが違います。
typeMismatch.java.lang.Integer={0}:整数を入力してください。
typeMismatch.java.util.Date={0}:yyyy/mm/ddで入力してください。
typeMismatch.age=年齢として有効な数値を入力してください。
}}
~
- 実行結果~
~
(エラー時)~
#ref(./sbvd-page9.png,wrap,nolink,結果)
~
(正常時)~
#ref(./sbvd-page10.png,wrap,nolink,結果)

~

~
~


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS