1. 概要

このチュートリアルでは、Hibernate Validatorに組み込まれているが、BeanValidation仕様の範囲外であるHibernateValidator制約を確認します。

Bean Validationの要約については、 Java Bean ValidationBasicsに関する記事を参照してください。

2. Hibernateバリデーターのセットアップ

少なくとも、依存関係にHibernateValidatorを追加する必要があります:

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.16.Final</version>
</dependency>

Hibernate Validatorは、他の多くの記事で取り上げたORMであるHibernateに依存しないことに注意してください。

さらに、ここで紹介する注釈の一部は、プロジェクトが特定のライブラリを使用している場合にのみ適用されます。 したがって、それらのそれぞれについて、必要な依存関係を示します。

3. お金に関連する値の検証

3.1. クレジットカード番号の検証

有効なクレジットカード番号は、Luhnのアルゴリズムを使用して計算するチェックサムを満たす必要があります。 @CreditCardNumber制約は、文字列がチェックサムを満たす場合に成功します。

@CreditCardNumberは、入力文字列に対して他のチェックを実行しません。 特に、入力の長さはチェックしません。 したがって、小さなタイプミスのために無効な番号のみを検出できます。

デフォルトでは、文字列に数字以外の文字が含まれている場合、制約は失敗しますが、それらを無視するように指示できます。

@CreditCardNumber(ignoreNonDigitCharacters = true)
private String lenientCreditCardNumber;

次に、スペースやダッシュなどの文字を含めることができます。

validations.setLenientCreditCardNumber("7992-7398-713");
constraintViolations = validator.validateProperty(validations, "lenientCreditCardNumber");
assertTrue(constraintViolations.isEmpty());

3.2. 金銭的価値の検証

@Currency バリデーターは、指定された金額が指定された通貨であるかどうかを確認します。

@Currency("EUR")
private MonetaryAmount balance;

クラスMonetaryAmountはJavaMoneyの一部です。 したがって、 @Currencyは、JavaMoneyの実装が利用可能な場合にのみ適用されます。

Java Moneyを正しく設定したら、制約を確認できます。

bean.setBalance(Money.of(new BigDecimal(100.0), Monetary.getCurrency("EUR")));
constraintViolations = validator.validateProperty(bean, "balance");
assertEquals(0, constraintViolations.size());

4. 範囲の検証

4.1. 数値および金額の範囲

Bean Validation仕様は、数値フィールドに適用できるいくつかの制約を定義しています。 これらに加えて、HibernateValidatorは便利なアノテーション@Range を提供します。これは、が@Minと@Maxの組み合わせとして機能し、範囲を包括的に一致させます。

@Range(min = 0, max = 100)
private BigDecimal percent;

@Min@Maxと同様に、@Rangeはプリミティブ数値タイプのフィールドとそのラッパーに適用できます。 BigIntegerおよびBigDecimal String 上記の表現、そして最後にMoneyValueフィールド。

4.2. 時間の長さ

ある時点を表す値の標準のJSR380アノテーションに加えて、HibernateValidatorにはDurationの制約も含まれています。 最初にJavaTimeのPeriodクラスとDurationクラスをチェックしてください。

したがって、プロパティに最小期間と最大期間を適用できます:

@DurationMin(days = 1, hours = 2)
@DurationMax(days = 2, hours = 1)
private Duration duration;

ここですべてを表示しなかった場合でも、注釈にはナノ秒から日までのすべての時間単位のパラメーターがあります。

デフォルトでは、 最小値と最大値が含まれます。 つまり、最小値または最大値とまったく同じ値が検証に合格します。

代わりに、境界値を無効にする場合は、を含むプロパティをfalseと定義します。

@DurationMax(minutes = 30, inclusive = false)

5. 文字列の検証

5.1. 文字列の長さ

2つのわずかに異なる制約を使用して、文字列が特定の長さであることを強制できます。

一般に、文字列の長さ( length メソッドで測定する文字列)が最小値と最大値の間にあることを確認する必要があります。 その場合、Stringプロパティまたはフィールドで@Lengthを使用します。

@Length(min = 1, max = 3)
private String someString;

ただし、Unicodeの複雑さのために、文字の長さとコードポイントの長さが異なる場合があります。 後者を確認する場合は、 @CodePointLength:を使用します。

@CodePointLength(min = 1, max = 3)
private String someString;

たとえば、文字列「aa \ uD835 \ uDD0A」は4文字の長さですが、コードポイントが3つしかないため、最初の制約に失敗し、2番目の制約を渡します。

また、両方の注釈を使用して、最小値または最大値を省略できます。

5.2. 数字の文字列のチェック

文字列が有効なクレジットカード番号であることを確認する方法については、すでに説明しました。 ただし、Hibernate Validatorには、数字の文字列に対する他のいくつかの制約が含まれています。

私たちがレビューしている最初のものは @LuhnCheck。 これはの一般化されたバージョンです @クレジットカード番号、 その中で同じチェックを実行しますが、追加のパラメーターを使用できます。

@LuhnCheck(startIndex = 0, endIndex = Integer.MAX_VALUE, checkDigitIndex = -1)
private String someString;

ここでは、パラメータのデフォルト値を示したので、上記は単純な@LuhnCheckアノテーションと同等です。

しかし、ご覧のとおり、サブストリング(startIndexおよびendIndex)でチェックを実行し、どの桁がチェックサム桁であるかを制約に伝えることができます。-1は最後の桁を意味します。チェックされたサブストリング内。

その他の興味深い制約には、モジュロ10チェック @ Mod10Check )およびモジュロ11チェック @ Mod11Check )があります。バーコードおよびISBNなどの他のコード用。

ただし、これらの特定のケースでは、Hibernate Validatorは、ISBNコードを検証するための制約 @ISBN と、EANバーコード@EAN制約を提供します。 。

5.3. URLとHTMLの検証

@Url 制約は、文字列がURLの有効な表現であることを確認します。 さらに、URLの特定のコンポーネントに特定の値があることを確認できます。

@URL(protocol = "https")
private String url;

したがって、プロトコル、ホスト、およびポートを確認できます。 それだけでは不十分な場合は、URLを正規表現と照合するために使用できるregexpプロパティがあります。

プロパティに「安全な」HTMLコードが含まれていることを確認することもできます(たとえば、スクリプトタグなし)。

@SafeHtml
private String html;

@SafeHtmlJSoupライブラリを使用します。これは依存関係に含まれている必要があります。

組み込みのタグホワイトリスト(ホワイトリストアノテーションのプロパティ)を使用し、追加のタグと属性(additionalTagsおよびadditionalTagsWithAttributes[ X242X]パラメータ)。

6. その他の制約

Hibernate Validatorには、特にブラジルとポーランドの識別番号、納税者コードなど、国や地域に固有の制約が含まれていることを簡単に説明します。 完全なリストについては、ドキュメントの関連セクションを参照してください。

また、@UniqueElements。を使用してコレクションに重複が含まれていないことを確認できます。

最後に、既存のアノテーションでカバーされていない複雑なケースの場合、JSR-223互換のスクリプトエンジンで記述されたスクリプトを呼び出すことができます。 もちろん、最新のJVMに含まれているJavaScript実装であるNashornに関するの記事でJSR-223に触れました。

この場合、アノテーションはクラスレベルであり、スクリプトはインスタンス全体で呼び出され、変数 _this:として渡されます。

@ScriptAssert(lang = "nashorn", script = "_this.valid")
public class AdditionalValidations {
    private boolean valid = true;
    // standard getters and setters
}

次に、インスタンス全体の制約を確認できます。

bean.setValid(false);
constraintViolations = validator.validate(bean);
assertEquals(1, constraintViolations.size());

7. 結論

この記事では、BeanValidation仕様で定義されている最小セットを超えるHibernateValidatorの制約をリストしました。

これらすべての例とコードスニペットの実装は、GitHubにあります。