1概要


Bean Validation

** は、アノテーションの形で宣言された一連の制約を使用してドメインオブジェクトを簡単に検証できるようにする標準の検証仕様です。

全体としては、http://hibernate.org/validator/[Hibernate Validator]などのBean検証実装の使用はかなり簡単ですが、これらの制約のいくつかがどのように実装されているかに関して、微妙ではあるが適切な違いを検討する価値があります。

このチュートリアルでは、


NotNull



@ NotEmpty、



@ NotBlank__の制約の違いについて説明します。


2 Mavenの依存関係

作業環境を素早くセットアップし、

@ NotNull



@ NotEmpty

、および

@ NotBlank

の制約の動作をテストするには、まず必要なMavenの依存関係を追加する必要があります。

この場合、ドメインオブジェクトの検証には、http://hibernate.org/validator/[Hibernate Validator]というBean検証参照実装を使用します。

これが

pom.xml

ファイルの関連セクションです。

<dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>6.0.13.Final</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.el</artifactId>
        <version>3.0.0</version>
     </dependency>
</dependencies>

我々のユニットテストではhttps://junit.org/junit5/[JUnit]とhttp://joel-costigliola.github.io/assertj/[AssertJ]を使用するので、httpsの最新版を確認してください。 ://search.maven.org/search?q = g:org.hibernate%20AND%20a:hibernate-validator


3

@ NotNull

制約

先に進んで、素朴な

UserNotNull

ドメインクラスとその

name

フィールドに

@ NotNull

アノテーションを付けて実装しましょう。

public class UserNotNull {

    @NotNull(message = "Name may not be null")
    private String name;

   //standard constructors/getters/toString
}

それでは、

@ NotNull

が実際にはどのように機能するのかを確認する必要があります。

__

そうするために、クラスのための簡単な単体テストを作成し、それのいくつかのインスタンスを検証しましょう:

@BeforeClass
public static void setupValidatorInstance() {
    validator = Validation.buildDefaultValidatorFactory().getValidator();
}

@Test
public void whenNotNullName__thenNoConstraintViolations() {
    UserNotNull user = new UserNotNull("John");
    Set<ConstraintViolation<UserNotNull>> violations = validator.validate(user);

    assertThat(violations.size()).isEqualTo(0);
}

@Test
public void whenNullName__thenOneConstraintViolation() {
    UserNotNull user = new UserNotNull(null);
    Set<ConstraintViolation<UserNotNull>> violations = validator.validate(user);

    assertThat(violations.size()).isEqualTo(1);
}

@Test
public void whenEmptyName__thenNoConstraintViolations() {
    UserNotNull user = new UserNotNull("");
    Set<ConstraintViolation<UserNotNull>> violations = validator.validate(user);

    assertThat(violations.size()).isEqualTo(0);
}

予想されたように、

@ NotNull

制約は制約されたフィールドにnull値を許可しませんでした。それでも、フィールドは空になることがあります。

これをよりよく理解するために、http://docs.jboss.org/ejb3/app-server/HibernateAnnotations/api/org/hibernate/validator/NotNullValidator.html#isV​​alid(java.lang.Object)[

NotNullValidator

クラスを見てみましょう。

@ NotNull

制約が使用する

isValid()

メソッド。メソッドの実装は本当に簡単です。

public boolean isValid(Object object) {
    return object != null;
}

上記のように、

@ NotNull

で制約されたフィールド(

CharSequence



Collection



Map、

、または

Arrayなど)はnullであってはなりません。しかしながら、空の値は完全に合法的です


4

@ NotEmpty

制約

それでは、サンプル

UserNotEmpty

クラスを実装し、

@ NotEmpty

制約を使用しましょう。

public class UserNotEmpty {

    @NotEmpty(message = "Name may not be empty")
    private String name;

   //standard constructors/getters/toString
}

クラスを設定したら、

name

フィールドに異なる値を割り当ててテストしましょう。

@Test
public void whenNotEmptyName__thenNoConstraintViolations() {
    UserNotEmpty user = new UserNotEmpty("John");
    Set<ConstraintViolation<UserNotEmpty>> violations = validator.validate(user);

    assertThat(violations.size()).isEqualTo(0);
}

@Test
public void whenEmptyName__thenOneConstraintViolation() {
    UserNotEmpty user = new UserNotEmpty("");
    Set<ConstraintViolation<UserNotEmpty>> violations = validator.validate(user);

    assertThat(violations.size()).isEqualTo(1);
}

@Test
public void whenNullName__thenOneConstraintViolation() {
    UserNotEmpty user = new UserNotEmpty(null);
    Set<ConstraintViolation<UserNotEmpty>> violations = validator.validate(user);

    assertThat(violations.size()).isEqualTo(1);
}


@ NotEmpty

アノテーションは

@ NotNull

クラスの

isValid()

実装を利用し、さらに提供されたオブジェクトのサイズ/長さ(もちろん検証されるオブジェクトの種類によって異なります)がゼロより大きいことを確認します。

一言で言えば、** これは、

@ NotEmpty

で制約されたフィールド(

CharSequence



Collection



Map、

、または__Arrayなど)がnullであってはならず、サイズ/長さがゼロより大きくなければならないことを意味します

さらに、

@ NotEmpty

アノテーションを

@Size.

と共に使用すると、さらに制限が厳しくなります。

その際、オブジェクトの最小サイズと最大サイズの値が指定された最小/最大範囲内になるように強制します。

@NotEmpty(message = "Name may not be empty")
@Size(min = 2, max = 32, message = "Name must be between 2 and 32 characters long")
private String name;


5

@ NotBlank

制約

同様に、

@ NotBlank

アノテーションを使ってクラスフィールドを制約することができます。

public class UserNotBlank {

    @NotBlank(message = "Name may not be blank")
    private String name;

   //standard constructors/getters/toString

}

同様に、

@ NotBlank

制約がどのように機能するのかを理解するための単体テストを実装することができます。

@Test
public void whenNotBlankName__thenNoConstraintViolations() {
    UserNotBlank user = new UserNotBlank("John");
    Set<ConstraintViolation<UserNotBlank>> violations = validator.validate(user);

    assertThat(violations.size()).isEqualTo(0);
}

@Test
public void whenBlankName__thenOneConstraintViolation() {
    UserNotBlank user = new UserNotBlank(" ");
    Set<ConstraintViolation<UserNotBlank>> violations = validator.validate(user);

    assertThat(violations.size()).isEqualTo(1);
}

@Test
public void whenEmptyName__thenOneConstraintViolation() {
    UserNotBlank user = new UserNotBlank("");
    Set<ConstraintViolation<UserNotBlank>> violations = validator.validate(user);

    assertThat(violations.size()).isEqualTo(1);
}

@Test
public void whenNullName__thenOneConstraintViolation() {
    UserNotBlank user = new UserNotBlank(null);
    Set<ConstraintViolation<UserNotBlank>> violations = validator.validate(user);

    assertThat(violations.size()).isEqualTo(1);
}


@ NotBlank

アノテーションはhttps://docs.jboss.org/hibernate/validator/6.0/api/org/hibernate/validator/internal/constraintvalidators/hv/NotBlankValidator.html[

NotBlankValidator

]クラスを使用してその文字をチェックしますシーケンスのトリミングされた長さは空ではありません。

public boolean isValid(
  CharSequence charSequence,
  ConstraintValidatorContext constraintValidatorContext)
    if (charSequence == null ) {
        return true;
    }
    return charSequence.toString().trim().length() > 0;
}

面白いことに、このメソッドはnull値に対してtrueを返します。そのため、

@ NotBlank

ではNULL値が許可されていると思われるかもしれませんが、実際には許可されていません。


  • @ NotNull

    クラスのisValid()メソッドは、

    @ NotBlank

    クラスのisValid()の後に呼び出されるため、NULL値は禁止されます。

簡単に言うと、

@ NotBlank

で制約された

String

フィールドはNULLではなく、トリミングされた長さはゼロより大きくなければなりません** 。


6. 並列比較

これまで、

@ NotNull



@ NotEmpty

、および

@ NotBlank

の制約がクラスフィールドに対してどのように機能するのかについて詳しく説明しました。

簡単に並べて比較してみましょう。そうすれば、制約の機能を鳥瞰図で確認でき、それらの違いを簡単に見つけることができます。


  • @ NotNull:

    制約のある

    CharSequence



    Collection



    Map、

    または


Array

はnullではない限り有効ですが、空でもかまいません
**

@ NotEmpty:

制約のある

CharSequence



Collection



Map、

、または


Array

は、nullでなく、サイズ/長さがそれより大きい限り有効です。
ゼロより
**

@ NotBlank:

制約のある

String

はnullでない限り有効です

そしてトリミングされた長さはゼロより大きいです


7. 結論

この記事では、Bean Validationに実装されている

NotNull



@ NotEmpty

、および

@ NotBlank

の制約を調べ、それらの類似点と相違点を強調しました。

いつものように、この記事に示されているすべてのコードサンプルはhttps://github.com/eugenp/tutorials/tree/master/javaxval[GitHubで利用可能]です。