ぺんぎんらぼ

お笑いとマンガ好きなしょぼしょぼWeb系エンジニアの日記です。たまに絵を描きます。

お笑いとマンガ好きなしょぼしょぼWeb系エンジニアの日記です

Spring Frameworkで使用できるBean Validationアノテーション一覧

Spring Frameworkで使用できるBean Validationのリファレンスです。
Webで検索しても、Bean Validationを網羅的に解説している日本語サイトがなかったので、Hibernateのサイトを参考に日本語のリファレンスを作成しました。

Bean ValidationはJSRで規格化されたもので、以下のバージョンが存在します。

  • JSR 303 (Bean Validation 1.0)
  • JSR 349 (Bean Validation 1.1)
  • JSR 380 (Bean Validation 2.0)

これらは規格なので、規格を実装したライブラリが必要です。リファレンス実装であり、Spring Validatorでも採用されているHibernate Validatorについて解説します。
Hibernate ValidatorはJSR 380の実装なので、基本的にJSR 380の規格に従った実装ですが、一部、Hibernate Validatorの独自拡張の要素があるので、その拡張についても併せて解説していきます。

Spring Frameworkでは、バリデーションの実装にHibernate Validatorを使用しているので、JSR 380で規格化されているバリデーションだけでなく、Hibernate Validatorの独自拡張のバリデーションも使用することができます。

オブジェクトバリデーション

オブジェクトに関するバリデーションです。
バリデーション対象の型はObjectクラスとになり、すべてのクラスをサポートします。

アノテーション チェック内容
@Null オブジェクトの値がNULLであることチェックします。
@NotNull オブジェクトの値がNULLでないことをチェックします。
画面の入力をフィームクラスのStringフィールドにバインドし、画面の入力値が未入力の場合、フィールドの値はNULLではなく空文字になるので、必須入力のチェックを実現する場合は@NotEmptyや@NotBlankを使用する必要があるので注意しましょう。
数値バリデーション

数値に関するバリデーションです。
バリデーション対象の型は数値型だけでなく、String型で数値表現の文字列に対してもチェック可能です。JSR 380でサポートされている数値型はBigDecimal, BigInteger, byte, short, int, longとラッパークラスですが、Hibernate Validatorでは拡張されており、Numberクラスを継承したクラスと金額を表現するjavax.money.MonetaryAmountクラスがサポートされています。

アノテーション チェック内容
@Max(value) 値が指定した最大値以下かどうかをチェックします。最大値の指定はlong型なので、最大値に小数部を含む値を指定することはできません。小数部を含む値を指定する場合は@DecimalMaxを使用します。
@Min(value) 値が指定した最小値以上かどうかをチェックします。最小値の指定はlong型なので、最小値に小数部を含む値を指定することはできません。小数部を含む値を指定する場合は@DecimalMinを使用します。
@DecimalMax(value, inclusive) 値が指定した最大値以下かどうかをチェックします。inclusive属性にfalseを指定した場合、値が指定された最大値より小さいかどうかをチェックします。最大値はBigDecimal文字列表現で指定します。
@DecimalMin(value, inclusive) 値が指定した最小値以上かどうかをチェックします。inclusive属性にfalseを指定した場合、値が指定された最小値より大きいかどうかをチェックします。最小値はBigDecimal文字列表現で指定します。
@Positive 値が正数であることをチェックします。0は正数とみなされません。
@PositiveOrZero 値が正数か0であることをチェックします。
@Negative 値が負数であることをチェックします。0は負数とみなされません。
@NegativeOrZero 値が負数か0であることをチェックします。
@Digits(integer, fraction) 値が指定した整数部の桁数および小数部の桁数以内であることをチェックします。
Hivernate Validation独自の数値バリデーション

Hivernate Validationで独自に追加されている数値に関するバリデーションがあります。

アノテーション チェック内容
@Range(min, max) 値が指定された最小値と最大値の間 (両端を含む) にあることをチェックします。JSR 380で規格化されている@Maxと@Minを指定したことと同等です。このアノテーションを指定できる型はBigDecimal, BigInteger, CharSequence, byte, short, int, longと、そのラッパークラスです。
@Currency(value) |javax.money.MonetaryAmountの通貨単位が、指定した通貨単位の一部であることをチェックします。このアノテーションを指定できる型はjavax.money.MonetaryAmountに限られます。
文字列バリデーション

文字列に関するバリデーションです。
バリデーション対象の型はjava.lang.CharSequenceインターフェースを実装したクラスとになります。

アノテーション チェック内容
@Email 文字列が有効な電子メールアドレスであることをチェックします。regexp属性とflags属性を使用して、電子メールであることを検証する文字列パターンを正規表現正規表現フラグで指定できます。
@NotBlank 文字列がNULLでなく、空白文字(半角スペースやタブ文字など)以外が含まれていることをチェックします。
@Pattern(regex, flags) 文字列が指定された正規表現とパターンマッチすることをチェックします。
Hivernate Validation独自の文字列バリデーション

Hivernate Validationで独自に追加されている文字列に関するバリデーションがあります。

アノテーション チェック内容
@CreditCardNumber(
ignoreNonDigitCharacters)
文字列がクレジットカード番号の構造にマッチすることをチェックします。この検証は、クレジット・カードの有効性の検証ではなく、Luhnチェックサム・テストに合格することを検証します。ignoreNonDigitCharacters属性にtrueを指定すると、数字以外の文字を無視できます。
@EAN(type) 文字列が有効なEANバーコードであることをチェックします。type属性でバーコードのタイプをEAN-8、EAN-13から選択できます。デフォルトはEAN-13です。
@ISBN 文字列が有効なISBNであるかどうかをチェックします。type属性はISBNのタイプをISBN-10、ISBN-13から選択できます。デフォルトはISBN-13です。
@Length(min, max) 文字列の長さが最小値と最大値の間であることをチェックします。JSR 380で規格化されている@Sizeと同等ですが、こちらは文字列専用です。
@CodePointLength(
min,
max,
normalizationStrategy)
Unicodeコード・ポイントの文字数が最小値と最大値の間であることをチェックします。サロゲートペア文字も1文字としてカウントします。normalizationStrategy属性で正規化の方法を選択できます。デフォルトは正規化なしです。
@LuhnCheck(
startIndex,
endIndex,
checkDigitIndex,
ignoreNonDigitCharacters)
文字列がLuhnチェックサムアルゴリズムを通過することをチェックします。startIndex属性とendIndex属性で文字列の一部に対してチェックすることができます。checkDigitIndex属性を使用すると、チェックディジットとして文字列内の任意のディジットを対象とすることができます。ignoreNonDigitCharacters属性にtrueを指定すると、数字以外の文字を無視できます。
@Mod10Check(
multiplier,
weight,
startIndex,
endIndex,
checkDigitIndex,
ignoreNonDigitCharacters)
文字列が汎用mod 10チェックサムアルゴリズムを通過することをチェックします。multiplier属性で乗数(デフォルトは3)、weight属性でウェイト(デフォルトは1)を指定します。startIndex属性とendIndex属性で文字列の一部に対してチェックすることができます。checkDigitIndex属性を使用すると、チェックディジットとして文字列内の任意のディジットを対象とすることができます。ignoreNonDigitCharacters属性にtrueを指定すると、数字以外の文字を無視できます。
@Mod11Check(
threshold,
startIndex,
endIndex,
checkDigitIndex,
ignoreNonDigitCharacters, treatCheck10As, treatCheck11As)
文字列がmod 11チェックサムアルゴリズムを通過することをチェックします。threshold属性でmod 11の乗数増加のしきい値(デフォルトは無限に増加)を指定します。treatCheck10As属性でチェックサムの値が10の時の文字(デフォルトは'X')を指定します。treatCheck11As属性でチェックサムの値が11の時の文字(デフォルトは'0')を指定します。startIndex属性とendIndex属性で文字列の一部に対してチェックすることができます。checkDigitIndex属性を使用すると、チェックディジットとして文字列内の任意のディジットを対象とすることができます。ignoreNonDigitCharacters属性にtrueを指定すると、数字以外の文字を無視できます。
@SafeHtml(
whitelistType,
additionalTags,
additionalTagsWithAttributes,
baseURI)
文字列に<script/>などの悪意のあるフラグメントが含まれていないことチェックします。このアノテーションを使用するにはjsoupライブラリが必要になります。whitelistType属性でホワイトリストタイプを定義することができます。additionalTags属性またはadditionalTagsWithAttributes属性で許可されるタグや属性を指定することができます。baseURI属性で相対URIを解決するために使用するベースURIを指定します。
@URL(
protocol,
host,
port,
regexp,
flags)
文字列がRFC 2396に従って有効なURLであることをチェックします。protocol属性やhost属性、port属性が指定されている場合、対応するURLが指定された値と一致することをチェックします。regexp属性とflags属性を指定すると、URL文字列のパターンを正規表現正規表現フラグで指定できます。デフォルトではjava.net.URLコンストラクタを使用して、URL文字列が有効なURLであるかどうかを検証します。
日時バリデーション

日時に関するバリデーションです。
バリデーション対象の型はjava.util.Date, java.util.Calendarに加えて、Java8で導入されたDate and Time API(java.timeパッケージ)がサポートされています。サポートされるDate and Time APIのクラスは、 Instant, LocalDate, LocalDateTime, LocalTime, MonthDay, OffsetDateTime, OffsetTime, Year, YearMonth, ZonedDateTime, java.time.chrono.HijrahDate, java.time.chrono.JapaneseDate, java.time.chrono.MinguoDate, java.time.chrono.ThaiBuddhistDateと幅広いです。Hibernate Validatorではサポートする型に、Joda Time date/time APIのクラスが追加されています。

アノテーション チェック内容
@Future 日付値が未来の日付であることをチェックします。
@FutureOrPresent 日付値が現在の日付か未来の日付であることをチェックします。
@Past 日付値が過去の日付であることをチェックします。
@PastOrPresent 日付値が現在の日付か過去の日付であることをチェックします。
Hivernate Validation独自の日時バリデーション

Hivernate Validationで独自に追加されている日時に関するバリデーションがあります。

アノテーション チェック内容
@DurationMax(days, hours, minutes, seconds, millis, nanos, inclusive) java.time.Durationの値が、各属性から作成された値より小さいことをチェックします。inclusive属性にtrueを指定すると同じ値が許可されます。このアノテーションを指定できる型はjava.time.Durationに限られます。
@DurationMin(days, hours, minutes, seconds, millis, nanos, inclusive) java.time.Durationの値が、各属性から作成された値より大きいことをチェックします。inclusive属性にtrueを指定すると同じ値が許可されます。このアノテーションを指定できる型はjava.time.Durationに限られます。
真偽値バリデーション

真偽値に関するバリデーションです。
バリデーション対象の型はbooleanとラッパークラスのBooleanクラスとになります。

アノテーション チェック内容
@AssertFalse 値がfalseであることを検証します。
@AssertTrue 値がtrueであることを検証します。
素数バリデーション

素数に関するバリデーションです。 バリデーション対象の型はjava.lang.CharSequenceインターフェースを実装したクラス、コレクションクラス、Mapインターフェースを継承したクラス、配列となります。Stringの場合は文字数、コレクション、Map、配列の場合は要素数が検証の対象となります。

アノテーション チェック内容
@NotEmpty 検証対象がNULLまたは要素数が0でないことをチェックします。
@Size(min, max) 検証対象の要素数が最小値と最大値の間 (両端を含む) であることをチェックします。
Hivernate Validation独自のコレクションバリデーション

Hivernate Validationで独自に追加されているコレクションクラスに関するバリデーションがあります。

アノテーション チェック内容
@UniqueElements コレクション内の要素が一意であることをチェックします。要素の比較にはequalsメソッドが使用されます。既定のエラーメッセージには重複する要素の一覧は含まれませんが、エラーメッセージを上書きし、メッセージパラメータ{duplicates}を使用することで、重複する要素をエラーメッセージに含めることができます。
Hivernate Validation独自のクラスバリデーション

Hivernate Validationで独自に追加されているクラスに関するバリデーションがあります。
これまでのバリデーションは変数に指定するもので、その変数の値を検証する、いわゆる「単項目バリデーション」でした。
このクラスバリデーションは他のバリデーションとは大きく違い、クラスに対するバリデーションなので、クラスの複数のフィールドを検証する、「複数項目バリデーション」を実現することができます。

アノテーション チェック内容
@ScriptAssert(lang, script, alias, reportOn) クラスに対して、指定されたスクリプト文字列を使用してチェックします。このバリデーションを使用するには、JSR 223を実装したライブラリが必要になります。スクリプト文字列は、JSR 223の実装ライブラリで使用できるのスクリプト言語で記述できます。このバリデーションはクラスレベルの検証ですが、reportOn属性で特定のフィールドに対してエラーをバインドすることができます。

@ScriptAssertの使用例

@ScriptAssertはスクリプト文字列で検証内容記述する自由度の高いバリデーションを実現するものです。
以下に使用例を挙げます。

@ScriptAssert(lang = "javascript", script = "_this.lastName.length() + _this.firstName.length() <= 30", reportOn = "firstName")
public class ProfileForm {

    /** 苗字 */
    private String lastName;

    /** 名前 */
    private String firstName;

@ScriptAssertの各属性の内容を見ていきます。

lang = "javascript"
スクリプトの種類を指定します。ここでは、スクリプト言語としてJava Scriptを指定しています。

script = "_this.lastName.length() + _this.firstName.length() <= 30"
検証に使用するスクリプト文字列を指定します。ここでは、フィールドのlastNameとfirstNameの文字数の合計が30文字以下であることを検証するスクリプトを指定しています。

reportOn = "firstName"
検証エラーになった場合、エラーをバインドするフィールドを指定します。ここではfirstNameフィールドにエラーをバインドしています。