Spring Boot:提供されているバリデーションの種類

バリデーションの基本的な使用方法は、以下の記事参照

olafnosuke.hatenablog.com

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} の間にしてください

文字列のバリデーション

@Email

入力値が妥当な電子メールアドレスであることをチェックする。メールアドレスの文字列パターンは正規表現で指定することもできる。
対象の型: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(全角) × ×