バリデーションの基本的な使用方法は、以下の記事参照
Spring Bootで使用できるバリデーションはココを参照。
数値のバリデーション
@Max
入力値が最大値以下であるかをチェックする。
対象の型:BigDecimal、BigInteger、byte、short、int、long
属性 | 属性の型 | 説明 |
---|---|---|
value | long | 最大値 |
/** 年齢*/ @Max(100) private int age;
# デフォルトメッセージ javax.validation.constraints.Max.message={value} 以下の値にしてください
@DecimalMax
入力値が最大値以下であるかをチェックする。少数を含む数値も最大値に設定できる。
対象の型:BigDecimal、BigInteger、byte、short、int、long、CharSequence
属性 | 属性の型 | 説明 |
---|---|---|
value | String | 最大値 |
inclusive | boolean | true:値が指定値以下かどうかをチェックする。 false:値が指定値より小さいかどうかをチェックする。 |
/** 年齢*/ @DecimalMax(value = "99.9", inclusive = false) private int age;
# デフォルトメッセージ javax.validation.constraints.DecimalMax.message={value} ${inclusive == true ? '以下の値にしてください' : 'より小さな値にしてください'}
@Min
入力値が最小値以上であるかをチェックする。
対象の型:BigDecimal、BigInteger、byte、short、int、long
属性 | 属性の型 | 説明 |
---|---|---|
value | long | 最大値 |
/** 年齢*/ @Min(20) private int age;
# デフォルトメッセージ javax.validation.constraints.Min.message={value} 以上の値にしてください
@DecimalMin
入力値が最小値以上であるかをチェックする。少数を含む数値も最小値に設定できる。
対象の型:BigDecimal、BigInteger、byte、short、int、long、CharSequence
属性 | 属性の型 | 説明 |
---|---|---|
value | String | 最小値 |
inclusive | boolean | true:値が指定値以上かどうかをチェックする。 false:値が指定値より大きいかどうかをチェックする。 |
/** 年齢*/ @DecimalMin(value = "19.9", inclusive = true) private int age;
# デフォルトメッセージ javax.validation.constraints.DecimalMin.message={value} ${inclusive == true ? '以上の値にしてください' : 'より大きな値にしてください'}
@Positive
入力値が正の数であるかをチェックする。0は正の数に含まれない。
対象の型:BigDecimal、BigInteger、byte、short、int、long、float、double
/** 気温*/ @Positive private double temperature;
# デフォルトメッセージ javax.validation.constraints.Positive.message = 0 より大きな値にしてください
@PositiveOrZero
入力値が正の数もしくは0であるかをチェックする。
対象の型:BigDecimal、BigInteger、byte、short、int、long、float、double
/** 気温*/ @PositiveOrZero private double temperature;
# デフォルトメッセージ javax.validation.constraints.PositiveOrZero.message = 0 以上の値にしてください
@Negative
入力値が負の数であるかをチェックする。0は負の数に含まれない。
対象の型:BigDecimal、BigInteger、byte、short、int、long、float、double
/** 気温*/ @Negative private double temperature;
# デフォルトメッセージ javax.validation.constraints.Negative.message = 0 より小さな値にしてください
@NegativeOrZero
入力値が負の数もしくは0であるかをチェックする。
対象の型:BigDecimal、BigInteger、byte、short、int、long、float、double
/** 気温*/ @NegativeOrZero private double temperature;
# デフォルトメッセージ javax.validation.constraints.NegativeOrZero.message = 0 以下の値にしてください
@Digits
入力値の整数部分・少数部分の桁数がそれぞれ指定値以下であることをチェックする。
対象の型:BigDecimal、BigInteger、byte、short、int、long、CharSequence
属性 | 属性の型 | 説明 |
---|---|---|
integer | int | 整数部分の桁数 |
fraction | int | 少数部分の桁数 |
/** 気温*/ @Digits(integer = 1, fraction = 1) private double temperature;
# デフォルトメッセージ javax.validation.constraints.Digits.message = 値は次の範囲にしてください (<整数 {integer} 桁>.<小数点以下 {fraction} 桁>)
@Range
入力値が指定された最小値以上、最大値以下の間にあることをチェックする。
対象の型:BigDecimal、BigInteger、byte、short、int、long、CharSequence
属性 | 属性の型 | 説明 |
---|---|---|
min | long | 最小値 |
max | long | 最大値 |
/** 年齢*/ @Range(min = 0, max = 100) private int age;
# デフォルトメッセージ org.hibernate.validator.constraints.Range.message = {min} から {max} の間にしてください
文字列のバリデーション
入力値が妥当な電子メールアドレスであることをチェックする。メールアドレスの文字列パターンは正規表現で指定することもできる。
対象の型:CharSequence
属性 | 属性の型 | 説明 |
---|---|---|
regexp | String | 妥当なメールアドレスかどうか検証するためのカスタム正規表現 |
flags | Pattern.Flag[] | 正規表現フラグ |
/** メールアドレス */ @Email private String mailAddress;
# デフォルトメッセージ javax.validation.constraints.Email.message = 電子メールアドレスとして正しい形式にしてください
@NotBlank
入力値がNULLでなく、最低でも1文字以上の空白でない文字が含まれていることをチェックする。
対象の型:CharSequence
/** 名前 */ @NotBlank private String name;
# デフォルトメッセージ javax.validation.constraints.NotBlank.message = 空白は許可されていません
@Pattern
入力値が指定した正規表現とマッチすることをチェックする。
対象の型:CharSequence
属性 | 属性の型 | 説明 |
---|---|---|
regexp | String | 正規表現 |
flags | Pattern.Flag[] | 正規表現フラグ |
/** ユーザーID */ @Pattern(regexp = "[a-zA-Z0-9]*") private String userId;
# デフォルトメッセージ javax.validation.constraints.Pattern.message = 正規表現 "{regexp}" にマッチさせてください
@CodePointLength
入力値のUnicodeコード・ポイントの文字数が最小値と最大値の間であることをチェックする。
サロゲートペア文字も1文字としてカウントする。
対象の型:CharSequence
属性 | 属性の型 | 説明 |
---|---|---|
min | int | 最小値 |
max | lint | 最大値 |
normalizationStrategy | NormalizationStrategy | 正規化の方法(デフォルト:正規化なし) |
/** 名前 */ @CodePointLength(min = 1, max = 3) private String name;
# デフォルトメッセージ org.hibernate.validator.constraints.CodePointLength.message = {min} から {max} の間の長さにしてください
@Length
入力値の文字数が指定された最小値以上、最大値以下の間にあることをチェックする。
対象の型:CharSequence
属性 | 属性の型 | 説明 |
---|---|---|
min | int | 最小値 |
max | lint | 最大値 |
/** 名前 */ @Length(min = 1, max = 20) private String name;
# デフォルトメッセージ org.hibernate.validator.constraints.Length.message = {min} から {max} の間の長さにしてください
@URL
入力値がRFC 2396に従って有効なURLであることをチェックする。
対象の型:CharSequence
属性 | 属性の型 | 説明 |
---|---|---|
protocol | String | プロトコル |
host | String | ホスト |
port | int | ポート番号 |
regexp | String | 正規表現 |
flags | Pattern.Flag[] | 正規表現フラグ |
/** URLチェック */ @URL private String url;
# デフォルトメッセージ org.hibernate.validator.constraints.URL.message = URL として正しい形式にしてください
@CreditCardNumber
入力値が正しいクレジットカード番号の形式かどうかをチェックする。
カードの有効性をチェックするものではない。
対象の型:CharSequence
属性 | 属性の型 | 説明 |
---|---|---|
ignoreNonDigitCharacters | boolean | true:数字以外の文字を無視する false:数字以外の文字を無視しない(デフォルト) |
/** カードNO */ @CreditCardNumber private String cardNumber;
# デフォルトメッセージ org.hibernate.validator.constraints.CreditCardNumber.message = 正しくないクレジットカードの番号です
@EAN
入力値が有効なEAN(European Article Number)またはUCP(Uniform Product Code Council)のコード番号かどうかをチェックする。
属性 | 属性の型 | 説明 |
---|---|---|
type | Type | バーコードのタイプ。EAN8とEAN13(デフォルト)から選択できる。 |
/** EANコード番号 */ @EAN private String ean;
@ISBN
入力値が有効なISBN(International Standard Book Number)のコード番号かどうかをチェックする。
属性 | 属性の型 | 説明 |
---|---|---|
type | Type | コードのタイプ。ISBN10、ISBN13(デフォルト)から選択できる。 |
/** ISBNコード番号 */ @ISBN private String isbn;
@LuhnCheck
入力値がLuhnModulo10チェックサムアルゴリズムに合格することをチェックする。
属性 | 属性の型 | 説明 |
---|---|---|
startIndex | int | チェックの始まりのインデックス。 文字列の一部に対してチェックしたいときに指定する。 |
endIndex | lint | チェックの終わりのインデックス。 文字列の一部に対してチェックしたいときに指定する。 |
checkDigitIndex | int | チェックディジットのインデックス。 デフォルトではチェックディジットは指定された範囲の最後の桁であると想定されている。 |
ignoreNonDigitCharacters | boolean | true:数字以外の文字を無視する false:数字以外の文字を無視しない(デフォルト) |
/** カードNO */ @LuhnCheck private String cardNumber;
日付のバリデーション
@Past
入力値が過去日(時間)であるかをチェックする。
過去かどうかは、実行環境のタイムゾーンを基準に判断される。
対象の型:Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate
/** 誕生日 */ @Past @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate birthday;
# デフォルトメッセージ javax.validation.constraints.Past.message = 過去の日付にしてください
@PastOrPresent
入力値が現在か過去日(時間)であるかをチェックする。
過去かどうかは、実行環境のタイムゾーンを基準に判断される。
対象の型:Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate
/** 誕生日 */ @PastOrPresent @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate birthday;
# デフォルトメッセージ javax.validation.constraints.PastOrPresent.message = 現在もしくは過去の日付にしてください
@Future
入力値が未来日(時間)であるかをチェックする。
未来かどうかは、実行環境のタイムゾーンを基準に判断される。
対象の型:Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate
/** 賞味期限 */ @Past @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate expirationDate;
# デフォルトメッセージ javax.validation.constraints.Future.message = 未来の日付にしてください
@FutureOrPresent
入力値が現在か未来日(時間)であるかをチェックする。
過去かどうかは、実行環境のタイムゾーンを基準に判断される。
対象の型:Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate
/** 賞味期限 */ @PastOrPresent @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate expirationDate;
# デフォルトメッセージ javax.validation.constraints.FutureOrPresent.message = 現在もしくは未来の日付にしてください
その他のバリデーション
@AssertTrue
入力値がtrueであることをチェックする。
対象の型:boolean
/** 検索フラグ */ @AssertTrue private boolean searched;
# デフォルトメッセージ javax.validation.constraints.AssertTrue.message = true にしてください
@AssertFalse
入力値がfalseであることをチェックする。
対象の型:boolean
/** 検索フラグ */ @AssertFalse private boolean searched;
# デフォルトメッセージ javax.validation.constraints.AssertFalse.message = false にしてください
@NotNull
入力値がnullでないことをチェックする。
対象の型:Object
/** 年齢 */ @NotNull private Integer age;
# デフォルトメッセージ javax.validation.constraints.NotNull.message = null は許可されていません
@Null
入力値がnullであることをチェックする。
対象の型:Object
/** 年齢 */ @Null private Integer age;
# デフォルトメッセージ javax.validation.constraints.Null.message = null にしてください
@NotEmpty
入力値がnullまたは空でないことをチェックする。
Collection, Map, 配列に付与した場合はnull/要素数が0でないことを、文字列に付与した場合はnull/空文字でないことがチェックされる。
対象の型:CharSequence、Collection、Map、Array
/** 名前 */ @NotEmpty private String name; /** 好きな食べ物 */ @NotEmpty private String[] favoriteFood;
# デフォルトメッセージ javax.validation.constraints.NotEmpty.message = 空要素は許可されていません
@Size
入力値の要素数(文字数)が指定された最小値以上、最大値以下の間にあることをチェックする。
文字列に付与した場合は、バイト数ではなく文字数でチェックされる。
対象の型:CharSequence、Collection、Map、Array
属性 | 属性の型 | 説明 |
---|---|---|
min | int | 最小値 |
max | lint | 最大値 |
/** 名前 */ @Size(min = 1, max = 20) private String name; /** 好きな食べ物 */ @Size(min = 1, max = 3) private String[] favoriteFood;
# デフォルトメッセージ javax.validation.constraints.Size.message = {min} から {max} の間のサイズにしてください
@UniqueElements
コレクション内の要素が一意であることをチェックする。
{duplicates}を使用することで、重複する要素をエラーメッセージに含めることができる。
対象の型:Collection
/** 配列要素重複チェック */ @UniqueElements private List<String> uniqueElements;
# デフォルトメッセージ org.hibernate.validator.constraints.UniqueElements.message = 要素は全てユニークにしてください
補足
日付/時間/日時:妥当性チェック
画面から文字列で与えられた日付/時間/日時をModelクラスにマッピングする際に、日付/時間/日時のフォーマット・妥当性チェックがデフォルトで行われている。
1. Modelクラス
/** 誕生日 */ @DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate birthday; /** 開始時間 */ @DateTimeFormat(pattern = "HH:mm:ss") private LocalTime startTime;
2. HTML
<div>誕生日</div> <div><input type="text" th:field="*{birthday}" /></div> <span th:if="${#fields.hasErrors('birthday')}" th:errors="*{birthday}" style="color: red"></span><br> <div>開始時間</div> <div><input type="text" th:field="*{startTime}" /></div> <span th:if="${#fields.hasErrors('startTime')}" th:errors="*{startTime}" style="color: red"></span><br>
3. メッセージプロパティ
ModelのString以外のフィールドに対して、変換不可能な値を送信した場合はorg.springframework.beans.TypeMismatchException
がスローされる。
デフォルトではエラー時のメッセージに例外の原因がそのまま表示されるが、src/main/resourcesにmessages.propertioes
を作成し、
そこでメッセージを定義することで任意のメッセージを表示することができる。
プロパティのキーは、typeMismatch.対象のFQCN
で定義する。
typeMismatch.java.time.LocalDate=フォーマットが不正、もしくは存在しない日付が指定されています。 typeMismatch.java.time.LocalTime=フォーマットが不正、もしくは存在しない時間が指定されています。
テキストボックスへの記入例とバリデーション結果を以下の表に示す。
項目 | 記入例 | バリデーション結果 |
---|---|---|
日付 | 2020/09/15 | NG:フォーマットが指定のものと異なるため |
日付 | 2020-09-15 | OK |
日付 | 2020-02-29 | OK |
日付 | 2020-09-31 | NG:2020-09-31は存在しないため |
日付 | 2021-02-29 | NG:2021-02-29は存在しないため |
時間 | 12:45 | NG:フォーマットが指定のものと異なるため |
時間 | 12:45:30 | OK |
時間 | 12:61:30 | NG:12:61:30は存在しないため |
時間 | 24:00:00 | NG:時間の範囲は00:00:00~23:59:59までのため |
数値チェック
日付の妥当性やフォーマットがmodelへのマッピング時にデフォルトでチェックされていたように、数値の場合もチェックされるのかを型別に調査した。
その結果、チェックが適当に実施されていると判断されたため、当該チェック用アノテーションは作成しないこととした。
エラー時のメッセージの変更は、日付の妥当性チェックの場合と同様。
○:マッピング成功
×:マッピング失敗
入力値 | int | short | long | float | double | byte | BigDecimal | BigInteger |
---|---|---|---|---|---|---|---|---|
0 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
5 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
-5 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
+5 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
0.05 | × | × | × | ○ | ○ | × | ○ | × |
005 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
09 | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
.01 | × | × | × | ○ | ○ | × | ○ | × |
-.001 | × | × | × | ○ | ○ | × | ○ | × |
0(全角) | ○ | ○ | ○ | × | × | ○ | ○ | ○ |
ー1(全角) | × | × | × | × | × | × | × | × |
5(全角) | ○ | ○ | ○ | × | × | ○ | ○ | ○ |