Spring Bootを利用したWEBアプリケーション上で、フォームクラスにアノテーションを指定することで、様々な単項目チェックを行うことができるが、そのアノテーションにgroups属性を指定することで、チェック処理の順番をつけることができる。
今回は、チェックを行うフォームクラスのアノテーションに、groups属性を指定してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装が完了していること。
サンプルプログラムの作成
作成したサンプルプログラムの構成は以下の通り。

なお、上記の赤枠は、前提条件のプログラムから追加・変更したプログラムである。
コントローラクラスの内容は以下の通りで、loginメソッド内で、フォームクラスに定義されたチェックを行うようになっている。また、チェックの順番を有効にするために、引数のフォームに「@Validated(All.class)」アノテーションを付与している。
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属性で何番目にチェックをするかを指定している。
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インタフェース内で、チェックの順番を定義している。
package com.example.demo.order;
public interface First {
}package com.example.demo.order;
public interface Second {
}package com.example.demo.order;
public interface Third {
}また、チェック処理で使用しているエラーメッセージは、以下のプロパティファイルで定義している。
#メッセージ
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ファイルの内容は以下の通りで、フォームクラスの入力チェックの結果を表示している。また、「パスワードを表示する」チェックボックスが選択された場合の動きを定義している。
<!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>.errorMessage{
color: #FF0000;
}
.fieldError{
background-color: #FFCCFF;
}'use strict';
// 「パスワードを表示する」チェックボックスが選択された場合の処理
function changePwType(pwCheck){
const pwd = document.getElementById('password');
if(pwCheck){
// パスワードのテキストボックスのタイプをテキストにする
pwd.setAttribute('type', 'text');
}else{
// パスワードのテキストボックスのタイプをパスワードにする
pwd.setAttribute('type', 'password');
}
}また、メイン画面のHTMLは以下の通りで、ログイン後の画面の内容を定義している。
<!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属性を指定することで、チェック処理の順番をつけることができる。





