見出し画像

Springフレームワーク09:ユーザー登録ページつくってみよう(エラーチェック関連)

データバインドエラーとバリデーションエラーの設定

【データバインドとは】
オブジェクトのフィールド(SignupForm.java)に「マッピング」すること
(オブジェクトのフィールドに取り出す)

【エラーチェック】
今回はデータバインド時のチェックとバリデーションエラーチェックを作る
(データバインド時のチェックは入力値を取り出した時のチェックだよー)


【エラーメッセージのカスタマイズ】
エラーメッセージ用のプロパティファイルを作成
src/main/resourcesの下に
新規ファイルmassages.propertiesを作る
(ファイルプロパティで文字コードはUTF-8にしましょう)

<データバインド時のチェック>

typeMismatch.signupForm.age=数値を入力してください
#↑int型でなければミスマッチ
typeMismatch.signupForm.birthday=yyyy/MM/dd形式で入力してください
#↑Date型でなければミスマッチ


<バリデーションエラーのチェック>
登録ボタンを押した時の判定だよー

バリデーションを実施するには、引数のフォームクラスに @Validated アノテーションを付ける

src/main/javaの下に
com.example.demo.login.domain.modelパッケージを作る
その下に新規クラス SignupForm.javaを作る

■実装方法
domain.modelのSignupForm.javaに
import org.hibernate.validator.constraints.Length;してから
アノテーションを入れる

@NotBlank <文字列がnull、空文字、空白スペースでない>
@NotNull <nullでない>
@NotEmpty <文字列やCollectinがnull、空でない>
@Email <文字列がEメール形式か>
@Length(min = 4, max = 100)
@Pattern(regexp = "^[a-zA-Z0-9]+$")
@DateTimeFormat(pattern = "yyyy/MM/dd")
@Min(20)
@Max(100)
@AssertFalse <Falseか>
など入れる


↓アノテーションが検出したエラー内容を表示させる

Springアノテーションをインポートする

SignupController.javaimport org.springframework.validation.annotation.Validated;

public String postSignUp(@ModelAttribute @Validated SignupForm form, BindingResult bindingResult, Model model)

※ バリデーションのチェック結果は BindingResult クラスに入っているため、バリデーションを使う場合はBindingResult クラスを引数に設定する。

(キャプチャーを入れる予定…)


↓バリデーションメッセージの編集(日本語にする)

src/main/resources/messages.propertiesに追記

<パターン1>

<注★>
★1・・・{0}はフィールド名が入るため、signupForm.userIdに"ユーザーID"を入れておく)

★2・・・違うModel.Attribute名でも同じフィールド名のものに共通のエラーメッセージ設定をしたい場合は、Model.Attribute名を省略可能(パターン2)

# ====================================
# バリデーションエラーメッセージ
# ====================================
#パターン1----------------------------
#ユーザーID
signupForm.userId=ユーザーID
#  ↑ ★1  ↑ ★2
NotBlank.signupForm.userId={0}を入力してください
Email.signupForm.userId={0}にはメールアドレスを入力してください

#パスワード
signupForm.password=パスワード
NotBlank.signupForm.password={0}を入力してください
Length.signupForm.password={0}は、{2}桁以上、{1}桁以下で入力してください
Pattern.signupForm.password={0}は半角英数字で入力してください

#ユーザー名
signupForm.userName=ユーザー名
NotBlank.signupForm.userName={0}を入力してください

#誕生日
signupForm.birthday=誕生日
NotNull.signupForm.birthday={0}を入力してください

<パターン3>
<注★>
★3・・・データ型に対してメッセージが紐付けられる

# パターン3 ---------------------------------------
#フィールド名
userId=ユーザーID
password=パスワード
userName=ユーザー名
birthday=誕生日
age=年齢

#バリデーションエラーメッセージ
NotBlank.java.lang.String={0}は必須入力です(パターン3)
#  ↑ ★3
Email.java.lang.String={0}はメールアドレス形式で入力してください(パターン3)
 ・
 ・
 ・

<パターン4>
<注★>
★4・・・パターン4ではアノテーションに対してメッセージが紐付けられる

# パターン4 ---------------------------------------
フィールド名
userId=ユーザーID
password=パスワード
userName=ユーザー名
birthday=誕生日
age=年齢

バリデーションエラーメッセージ
NotBlank={0}は必須入力です(パターン4)
#  ↑ ★4
Email={0}はメールアドレス形式で入力してください(パターン4)
 ・
 ・
 ・

<パターン5>
<注★>
★5・・・独自のキーを設定する

# パターン5 ---------------------------------------
#フィールド名
userId=ユーザーID
password=パスワード
userName=ユーザー名
birthday=誕生日
age=年齢

#必須入力チェック
require_check={0}は必須入力です(パターン5)
#  ↑ ★5
#メールアドレス形式チェック
email_check={0}はメールアドレス形式で入力してください(パターン5)
 ・
 ・
 ・


↓messageと独自キーを紐付ける

【各アノテーションにmessage属性を付ける】
各アノテーションにmessage属性を付けることで、 message.properties の独自キーと紐付けることができる
message="{<独自キー名>}"

※直接エラーメッセージを指定する場合の記述
@NotBlank(message="パスワードを入力してください") String password;

【文字コードの設定
デフォルトのままでは日本語を使うと文字化けする



com.example.demo配下にWebConfigクラスを作る

package com.example.demo;

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

@Configuration
public class WebConfig {

 public MessageSource messageSourse() {
   ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();

   //メッセージのプロパティ―ファイル名(デフォルト)を指定します
   //下記ではmessages.propertiesファイルがセットされます
   bean.setBasename("classpath:messages");

   //メッセージプロパティ―の文字コード
   bean.setDefaultEncoding("UTF-8");
     ・
     ・
     ・

【フォームの各入力部分にエラーメッセージを出す】
src/main/resources/templates/signup.htmlに追記
thymeleafと、BootStrap4のクラス名、シンボルを使用

<注★>
★6・・・'is-invalid'はフィールドにエラーが出た際のエラー時のシンボル
★7・・・エラーメッセージを赤文字(class="text-danger")で表示

<div class="form-group col-sm-12" th:classappend="${#fields.hasErrors('userId')} ? 'is-invalid'">
<!-- ↑ ★6 -->
<input Type="text" class="form-control" th:field="*{userId}"/>
<span class="text-danger"
   th:if="${#fields.hasErrors('userId')}"
   th:errors="*{userId}">
   userID error
</span>
<!-- ↑ ★7 -->
     ・
     ・
     ・

【エラーメッセージ1つずつ出す(バリデーションのグループ実行)】

画像1

com.example.demo.login.domain.model配下に
インタフェース ValidGroup1.java ValidGroup2.java ValidGroup3.javaを作る



同じ階層に上記をとりまとめる
インタフェース GroupOrder.javaを作る

<注★>
★8・・・バリデーショングループの実行順番を記述

package com.example.demo.login.domain.model;

import javax.validation.GroupSequence;

//↓ ★8
@GroupSequence({ ValidGroup1.class, ValidGroup2.class, ValidGroup3.class })
public interface GroupOrder {
}




SignupController.javaの@Validatedに (GroupOrder.class)を 追記

public String postSignUp(@ModelAttribute("signupForm") @Validated(GroupOrder.class) SignupForm form, BindingResult bindingResult, Model model)




com.example.demo.login.domain.model配下のSignupForm.javaに追記
アノテーションにgroups = ValidGroup〇.classを追記
〇は(1~3)

@NotBlank(groups = ValidGroup1.class, message="{require_check}")

※ この方法では、ValidGroup1が全て解消されてから2のチェックに移る仕様です!(あくまで授業の課題なので…)

もしも気に入ったら、サポートお願いします! おやつを買いますので、餌付けができます。