Spring Bootを利用したWEBアプリケーション上で、フォームクラスにアノテーションを指定することで、様々な単項目チェックを行うことができるが、そのアノテーションにgroups属性を指定することで、チェック処理の順番をつけることができる。
今回は、チェックを行うフォームクラスのアノテーションに、groups属性を指定してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装が完了していること。
サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。
なお、上記の赤枠は、前提条件のプログラムから追加・変更したプログラムである。
コントローラクラスの内容は以下の通りで、loginメソッド内で、フォームクラスに定義されたチェックを行うようになっている。また、チェックの順番を有効にするために、引数のフォームに「@Validated(All.class)」アノテーションを付与している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | package com.example.demo; import com.example.demo.order.All; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.bind.support.SessionStatus; /** * コントローラクラス * 「@SessionAttributes(types = DemoForm.class)」により、 * 生成したFormオブジェクトをセッションとしてもたせている */ @Controller @SessionAttributes(types = DemoForm.class) public class DemoController { /** * Formオブジェクトを初期化して返却する * @return Formオブジェクト */ @ModelAttribute("demoForm") public DemoForm createDemoForm(){ DemoForm demoForm = new DemoForm(); return demoForm; } /** * ログイン画面に遷移する * @return ログイン画面へのパス */ @GetMapping("/") public String index(){ return "login"; } /** * エラーチェックを行い、エラーが無ければメイン画面に遷移し、 * エラーがあればログイン画面のままとする * @param demoForm Formオブジェクト * @param result バインド結果 * @return メイン画面またはログイン画面へのパス */ @PostMapping("/login") public String login(@Validated(All.class) DemoForm demoForm , BindingResult result){ // formオブジェクトのチェック処理を行う if(result.hasErrors()){ // エラーがある場合は、ログイン画面のままとする return "login"; } // メイン画面に遷移する return "main"; } /** * ログイン画面に戻る * @param sessionStatus セッションステータス * @return ログイン画面 */ @PostMapping(value = "/back") public String back(SessionStatus sessionStatus){ // セッションオブジェクトを破棄する sessionStatus.setComplete(); return "login"; } } |
また、フォームクラスの内容は以下の通りで、IDとパスワードの入力チェックを行うようになっている。また、groups属性で何番目にチェックをするかを指定している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | package com.example.demo; import com.example.demo.order.First; import com.example.demo.order.Second; import com.example.demo.order.Third; import lombok.Data; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Pattern; /** * Formオブジェクトのクラス */ @Data public class DemoForm { /** ID */ // 必須指定・桁数は3桁・半角数字で入力可能とする // 必須チェックは1回目に、それ以外のチェックは2回目に行う @NotEmpty(groups = First.class) @Length(min = 3, max = 3, groups = Second.class) @Pattern(regexp = "^[0-9]+$" , message = "{validation.number}" , groups = Second.class) private String id; /** パスワード */ // 必須指定・桁数は8~10桁・半角英数字で入力可能とする // 必須チェックは1回目に、桁数チェックは2回目に、 // 半角英数字チェックは3回目にそれぞれ行う @NotEmpty(groups = First.class) @Length(min = 8, max = 10, groups = Second.class) @Pattern(regexp = "^[a-zA-Z0-9]+$" , message = "{validation.alpha-number}" , groups = Third.class) private String password; } |
さらに、フォームクラスの入力チェックのgroups属性で指定した順番を定義する各インタフェースの内容は以下の通りで、Allインタフェース内で、チェックの順番を定義している。
1 2 3 4 | package com.example.demo.order; public interface First { } |
1 2 3 4 | package com.example.demo.order; public interface Second { } |
1 2 3 4 | package com.example.demo.order; public interface Third { } |
また、チェック処理で使用しているエラーメッセージは、以下のプロパティファイルで定義している。
1 2 3 4 5 6 7 8 9 10 11 | #メッセージ javax.validation.constraints.NotEmpty.message={0}を入力してください。 org.hibernate.validator.constraints.Length.message ={0}は${min == max ? min += '桁で入力してください' : min += '桁以上' += max += '桁以下で入力してください'} validation.number={0}は半角数字で入力してください。 validation.alpha-number={0}は半角英数字で入力してください。 #フィールド名 id=ID password=パスワード |
なお、上記プロパティファイルでは、Lengthアノテーションを改行して表示しているが、実際は改行しない設定になっている。
さらに、ログイン画面とそのCSS,JSファイルの内容は以下の通りで、フォームクラスの入力チェックの結果を表示している。また、「パスワードを表示する」チェックボックスが選択された場合の動きを定義している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <!DOCTYPE html> <html lang="ja" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <link th:href="@{/login.css}" rel="stylesheet" type="text/css" /> <script type="text/javascript" th:src="@{/login.js}"></script> <title>ログイン画面</title> </head> <body> <form method="post" th:action="@{/login}" th:object="${demoForm}"> <p>ID・パスワードを入力の上、「ログイン」ボタンを押下してください。</p> <ul> <li th:each="error : ${#fields.detailedErrors()}" class="errorMessage"> <span th:text="${error.message}">ここにエラーメッセージを表示する</span> </li> </ul> <table border="0"> <tr> <td align="left" valign="top">ID:</td> <td> <input type="text" maxlength="3" th:value="*{id}" th:field="*{id}" th:errorclass="fieldError" /> </td> </tr> <tr> <td align="left" valign="top">パスワード:</td> <td> <input type="password" maxlength="10" th:value="*{password}" th:field="*{password}" th:errorclass="fieldError" /> </td> </tr> <tr> <td align="left" valign="top" colspan="2"> <input type="checkbox" id="pwCheck" onclick="changePwType(this.checked)">パスワードを表示する </td> </tr> </table> <br/><br/> <input type="submit" value="ログイン" /> </form> </body> </html> |
1 2 3 4 5 6 | .errorMessage{ color: #FF0000; } .fieldError{ background-color: #FFCCFF; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 | 'use strict'; // 「パスワードを表示する」チェックボックスが選択された場合の処理 function changePwType(pwCheck){ const pwd = document.getElementById('password'); if(pwCheck){ // パスワードのテキストボックスのタイプをテキストにする pwd.setAttribute('type', 'text'); }else{ // パスワードのテキストボックスのタイプをパスワードにする pwd.setAttribute('type', 'password'); } } |
また、メイン画面のHTMLは以下の通りで、ログイン後の画面の内容を定義している。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!DOCTYPE html> <html lang="ja" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>メイン画面</title> </head> <body> メイン画面に遷移しました。<br/><br/> <form method="post" th:action="@{/back}"> <input type="submit" value="ログアウト"/> </form> </body> </html> |
その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-check-order/demo
サンプルプログラムの実行結果
サンプルプログラムの実行結果は、以下の通り。
1) Spring Bootアプリケーションを起動し、「http:// (ホスト名):(ポート番号)/」にアクセスすると、以下のように、login.htmlの画面が表示されることが確認できる。
2) 何も指定せず「ログイン」ボタンを押下すると、以下のように、エラーメッセージが表示されることが確認できる。
3) IDのみ指定し「ログイン」ボタンを押下すると、以下のように、パスワードの必須チェック(1回目)でエラーになるため、IDの桁数・文字数チェック(2回目)のチェックが行われないことが確認できる。
4) ID・パスワード(いずれも2回目のチェックでエラーになる値)を指定し「ログイン」ボタンを押下すると、以下のようなエラーが発生することが確認できる。
5) ID・パスワードを指定し、「パスワードを表示する」チェックを押下すると、以下のように、パスワードが表示されることが確認できる。
6) ID(エラーでない値)、パスワード(3回目のチェックでエラーになる値)を指定し「ログイン」ボタンを押下すると、以下のようなエラーが発生することが確認できる。
7) ID・パスワード(いずれもエラーでない値)を指定し「ログイン」ボタンを押下すると、以下のように、メイン画面に遷移できることが確認できる。
要点まとめ
- Spring Bootを利用したWEBアプリケーション上で、フォームクラスにアノテーションを指定することで、様々な単項目チェックを行うことができるが、そのアノテーションにgroups属性を指定することで、チェック処理の順番をつけることができる。