1. 概要

このクイックチュートリアルでは、 Java Beanを標準フレームワークであるJSR380( Bean Validation 2.0とも呼ばれます)で検証するための基本について説明します。

ユーザー入力の検証は、ほとんどのアプリケーションで非常に一般的な要件です。 そして、Java Bean Validationフレームワークは、この種のロジックを処理するための事実上の標準になりました。

2. JSR 380

JSR 380は、JakartaEEおよびJavaSEの一部であるBean検証用のJavaAPIの仕様です。 これにより、 @NotNull @Min @Max などのアノテーションを使用して、Beanのプロパティが特定の基準を満たすことが保証されます。

このバージョンにはJava8以降が必要であり、型注釈やオプションLocalDateなどの新しい型のサポートなどのJava8で追加された新機能を利用します。

仕様の詳細については、 JSR380をお読みください。

3. 依存関係

Mavenの例を使用して、必要な依存関係を示します。 しかしもちろん、これらのjarファイルはさまざまな方法で追加できます。

3.1. 検証API

JSR 380仕様によると、 validation-apidependencyには標準の検証APIが含まれています。

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>

3.2. 検証APIリファレンス実装

Hibernate Validatorは、検証APIのリファレンス実装です。

これを使用するには、次の依存関係を追加する必要があります。

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

簡単なメモ: hibernate-validatorは、Hibernateの永続性の側面から完全に分離されています。したがって、依存関係として追加することにより、これらの永続性の側面をプロジェクトに追加しません。

3.3. 式言語の依存関係

JSR 380は変数補間をサポートし、違反メッセージ内の式を許可します。

これらの式を解析するために、GlassFishから javax.el 依存関係を追加します。これには、式言語仕様の実装が含まれています。

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.el</artifactId>
    <version>3.0.0</version>
</dependency>

4. 検証アノテーションの使用

ここでは、ユーザー beanを使用して、簡単な検証を追加します。

import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.validation.constraints.Email;

public class User {

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

    @AssertTrue
    private boolean working;

    @Size(min = 10, max = 200, message 
      = "About Me must be between 10 and 200 characters")
    private String aboutMe;

    @Min(value = 18, message = "Age should not be less than 18")
    @Max(value = 150, message = "Age should not be greater than 150")
    private int age;

    @Email(message = "Email should be valid")
    private String email;

    // standard setters and getters 
}

この例で使用されているすべてのアノテーションは、標準のJSRアノテーションです。

  • @NotNull は、注釈付きのプロパティ値がnullではないことを検証します。
  • @AssertTrue は、注釈付きのプロパティ値がtrueであることを検証します。
  • @Size は、注釈付きのプロパティ値が属性minmaxの間のサイズであることを検証します。 String Collection Map 、および配列のプロパティに適用できます。
  • @Min は、注釈付きプロパティの値がvalue属性以上であることを検証します。
  • @Max は、注釈付きプロパティの値がvalue属性以下であることを検証します。
  • @Email は、注釈付きプロパティが有効な電子メールアドレスであることを検証します。

一部の注釈は追加の属性を受け入れますが、メッセージ属性はそれらすべてに共通です。 これは、それぞれのプロパティの値が検証に失敗したときに通常表示されるメッセージです。

そして、JSRで見つけることができるいくつかの追加の注釈:

  • @NotEmpty は、プロパティがnullまたは空でないことを検証します。 String Collection Map 、またはArrayの値に適用できます。
  • @NotBlank はテキスト値にのみ適用でき、プロパティがnullまたは空白でないことを検証します。
  • @Positiveおよび@PositiveOrZeroは数値に適用され、厳密に正、または0を含む正であることを検証します。
  • @Negativeおよび@NegativeOrZeroは数値に適用され、それらが厳密に負であるか、0を含む負であることを検証します。
  • @Pastおよび@PastOrPresentは、日付値が過去または現在を含む過去であることを検証します。 Java8で追加されたものを含む日付タイプに適用できます。
  • @Futureおよび@FutureOrPresentは、日付値が将来、または現在を含む将来であることを検証します。

検証アノテーションはコレクションの要素にも適用できます

List<@NotBlank String> preferences;

この場合、設定リストに追加された値が検証されます。

また、仕様は、Java8の新しいオプション型をサポートしています。

private LocalDate dateOfBirth;

public Optional<@Past LocalDate> getDateOfBirth() {
    return Optional.of(dateOfBirth);
}

ここで、検証フレームワークは LocalDate 値を自動的にアンラップし、検証します。

5. プログラムによる検証

Springなどの一部のフレームワークには、アノテーションを使用するだけで検証プロセスをトリガーする簡単な方法があります。 これは主に、プログラムによる検証APIを操作する必要がないようにするためです。

それでは、手動ルートを使用して、プログラムで設定してみましょう。

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

Beanを検証するには、最初にValidatorオブジェクトが必要です。これはValidatorFactoryを使用して構築されています。

5.1. Beanの定義

次に、この無効なユーザーを設定します— null name値を使用します。

User user = new User();
user.setWorking(true);
user.setAboutMe("Its all about me!");
user.setAge(50);

5.2. Beanを検証する

Validator ができたので、validateメソッドに渡すことでBeanを検証できます。

User オブジェクトで定義された制約の違反は、Setとして返されます。

Set<ConstraintViolation<User>> violations = validator.validate(user);

違反を繰り返すことにより、getMessageメソッドを使用してすべての違反メッセージを取得できます。

for (ConstraintViolation<User> violation : violations) {
    log.error(violation.getMessage()); 
}

この例( ifNameIsNull_nameValidationFails )では、セットに「名前をnullにすることはできません」というメッセージを含む単一のConstraintViolationが含まれます。

6. 結論

この記事では、標準のJava検証APIの単純なパスに焦点を当てました。 javax.validationアノテーションとAPIを使用したBean検証の基本を示しました。

いつものように、この記事の概念の実装とすべてのコードスニペットは、GitHubにあります。