前提・実現したいこと
該当のソースコード
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"></meta> <link th:href="@{/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css}"rel="stylesheet"></link> <script th:src="@{/webjars/jquery/1.11.1/jquery.min.js}"></script> <script th:src="@{/webjars/bootstrap/3.3.7-1/js/bootstrap.min.js}"></script> <title>Login</title> </head> <body> <div class="col-sm-5"> <div class="page-header"> <h1>ユーザー登録画面</h1> </div> <!-- th:action Springセキリュティ使う時 --> <!-- th:object Modelに登録されているオブジェクト受け取れる --> <form method="post" th:action="@{/signup}"th:object="${signupForm}"> <table class="table table-bordered table-hover"> <tr> <th class="active col-sm-3">ユーザーID</th> <td> <!-- エラー用のcss th:classppend--> <div class="formg-roup"th:classppend="${#fields.hasErrors('userId')}?'has-error'"> <!-- th:field オブジェクトのフィールド--> <input type="text"class="form-control" th:field="*{userId}"> <!-- th:if 条件式設定(trueだとタグが表示) --> <span class="text-danger"th:if="${#fields.hasErrors('userId')}"th:errors="*{userId}"> userId error </span> </div> </td> </tr> <tr> <th class="active">パスワード</th> <td> <div class="form-group"th:classppend="${#fields.hasErrors('password')}?'has-error'"> <input type="text"class="form-control" th:field="*{password}"> <span class="text-danger"th:if="${#fields.hasErrors('password')}"th:errors="*{password}"> password error </span> </div> </td> </tr> <tr> <th class="active">ユーザー名</th> <td> <div class="form-group"th:classppend="${#fields.hasErrors('userName')}?'has-error'"> <input type="text"class="form-control" th:field="*{userName}"> <span class="text-danger"th:if="${#fields.hasErrors('userName')}"th:errors="*{userName}"> userName error </span> </div> </td> </tr> <tr> <th class="active">誕生日</th> <td> <div class="form-group"th:classppend="${#fields.hasErrors('birthday')}?'has-error'"> <input type="text"class="form-control"placeholder="yyyy/MM/dd" th:field="*{birthday}"> <span class="text-danger"th:if="${#fields.hasErrors('birthday')}"th:errors="*{birthday}"> birthday error </span> </div> </td> </tr> <tr> <th class="active">年齢</th> <td> <div class="formgroup"th:classppend="${#fields.hasErrors('age')}?'has-error'"> <input type="text"class="formcontrol" th:field="*{age}"> <span class="text-danger"th:if="${#fields.hasErrors('age')}"th:errors="*{age}"> age error </span> </div> </td> </tr> <tr> <th class="active">結婚</th> <td> <div class="form-group"th:classppend="${#fields.hasErrors('marriage')}?'has-error'"> <div th:each="item:${radioMarriage}"> <!-- SignupControllerクラスで取得したMapを繰り返し --> <!-- th:text 画面表示される文字列を指定 --> <!-- th:value 画面からControllerクラスに送る値指定 --> <input type="radio"name="radioMarrige" th:text="${item.key}" th:value="${item.value}" th:field="*{marriage}"> <span class="text-danger"th:if="${#fields.hasErrors('marriage')}"th:errors="*{marriage}"> radioMarriage error </span> </div> </div> </td> </tr> </table> <ul> <!-- エラーメッセージの一覧表示 --> <li th:each="error:${#fields.detailedErrors()}"> <span th:text="${error.message}">Error message</span> </li> </ul> <button class="btn btn-primary"type="submit"> ユーザー登録 </button> </form> </div> </body> </html>
package com.example.demo.controllers; import java.util.LinkedHashMap; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import com.exmple.demo.models.GroupOrder; import com.exmple.demo.models.SignupForm; @Controller public class SignupController { //ラジオボタンの実装 private Map<String, String>radioMarriage; //ラジオボタンの初期化メソッド private Map<String, String>initRadioMarrige(){ Map<String, String> radio = new LinkedHashMap<>(); //putメソッドでMapに格納 radio.put("既婚", "true"); radio.put("未婚", "false"); return radio; } @GetMapping("/signup") public String getSignUp(@ModelAttribute SignupForm form,Model model) { //ラジオボタンの初期化メソッドの呼び出し radioMarriage = initRadioMarrige(); //ラジオボタン用のMapをModelに登録 model.addAttribute("radioMarriage",radioMarriage); return "login/signup"; } //ユーザー登録画面のPOST用コントローラー @PostMapping("/signup") //@ModelAttribute 自動でModelクラスに登録してくれる(addAttribute) //BindingResult データバインド結果を受け取る //@Validated バリデーション実施 public String postSignUp(@ModelAttribute @Validated(GroupOrder.class) SignupForm form,BindingResult bindingResult,Model model) { //hasErrorsでデータバインドに失敗しているかわかる if (bindingResult.hasErrors()) { //GETリクエスト用のメソッド呼び出し、ユーザー登録画面に戻る return getSignUp(form, model); } System.out.println(form); return "redirect:/login"; } }
package com.exmple.demo.models; import java.util.Date; import javax.validation.constraints.AssertFalse; import javax.validation.constraints.Email; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; import org.hibernate.validator.constraints.Length; import org.springframework.format.annotation.DateTimeFormat; import lombok.Data; @Data public class SignupForm { //groups属性(classオブジェクトの配列を指定 インターフェイスのみ) //groups属性にインターフェイスのクラスを指定してフィールドとグループの紐付け @NotBlank(groups = ValidGroup1.class) @Email(groups = ValidGroup2.class) private String userId;//ユーザーID @NotBlank(groups = ValidGroup1.class) @Length(min=4,max=100,groups = ValidGroup2.class) @Pattern(regexp = "^[a-zA-Z0-9]+$",groups = ValidGroup3.class) private String password;//パスワード @NotBlank(groups = ValidGroup1.class) private String userName;//ユーザー名 //画面から渡された文字列を日付型に変換 //pattern属性でどのようなフォーマットでデータが渡されてくるか指定 @NotNull(groups = ValidGroup1.class) @DateTimeFormat(pattern = "yyyy/MM/dd") private Date birthday;//誕生日 @Min(value = 20,groups = ValidGroup2.class) @Max(value = 100,groups = ValidGroup2.class) private int age;//年齢 //@AssertFalse falseのみ可能 @AssertFalse(groups = ValidGroup2.class) private boolean marriage;//結婚ステータス }
package com.exmple.demo.models; import javax.validation.GroupSequence; //@GroupSequence バリエーショングループの実行順序設定 @GroupSequence({ValidGroup1.class,ValidGroup2.class,ValidGroup3.class}) public interface GroupOrder { }
package com.exmple.demo.models; public interface ValidGroup1 { }
#messages.properties typeMismatch.signupForm.age=数値を入力してください typeMismatch.signupForm.birthday=yyyy/MM/dd形式で入力してください userId=ユーザーID password=パスワード userName=ユーザー名 birthday=誕生日 age=年齢 #必須入力チェック require_check={0}は必須入力です #メールアドレス形式チェック email_check={0}はメールアドレス形式で入力してください #入力文字数チェック length_check={0}は、{2}桁以上、{1}桁以下の桁数で入力してください #フォーマットチェック pattern_check={0}は半角英数字で入力してください #下限値チェック min_check={0}は{1}以上を入力してください #上限値チェック max_check={0}は、{1}以下を入力してください #ステータスチェック false_check=falseの場合のみ登録できます
試したこと
バリデーションでグループを作成するために、インターフェイスを作成しました
messages.propertiesのところが読まれてないってことでいいのでしょうか?
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。