65.2. Bean Validation を使用したサービスの開発

65.2.1. サービス Bean のアノテーション

概要

Bean 検証でサービスを開発する最初のステップは、関連する検証アノテーションをサービスを表す Java クラスまたはインターフェイスに適用することです。検証アノテーションを使用すると、メソッドパラメーター、戻り値、およびクラスフィールドに制約を適用でき、サービスが呼び出されるたびに、実行時にチェックされます。

単純な入力パラメーターの検証

パラメーターが簡単な Java 型である場合にサービスメソッドのパラメーターを検証するには、Bean バリデーション API (javax.validation.constraints パッケージ) から制約アノテーションを適用できます。たとえば、以下のコード例は、nullness (@NotNull アノテーション) の両方のパラメーターをテストし、id 文字列が \\d+ 正規表現 (@Pattern アノテーション) と一致するかどうか、および name 文字列の長さが 1 から 50 の範囲にあるかどうかをテストします。

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
...
@POST
@Path("/books")
public Response addBook(
        @NotNull @Pattern(regexp = "\\d+") @FormParam("id") String id,
        @NotNull @Size(min = 1, max = 50) @FormParam("name") String name) {
    // do some work
    return Response.created().build();
}

複雑な入力パラメーターの検証

複雑な入力パラメーター (オブジェクトインスタンス) を検証するには、以下の例のように @Valid アノテーションをパラメーターに適用します。

import javax.validation.Valid;
...
@POST
@Path("/books")
public Response addBook( @Valid Book book ) {
    // do some work
    return Response.created().build();
}

@Valid アノテーションは、単独では制約を指定しません。Book パラメーターに @Valid のアノテーションを付けると、検証制約を探すために (再帰的に) Book クラスの定義内を調べるように、検証エンジンを効果的に指示します。この例では、以下のように、Book クラスは id および name フィールドの検証制約で定義されます。

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
...
public class Book {
    @NotNull @Pattern(regexp = "\\d+") private String id;
    @NotNull @Size(min = 1, max = 50) private String name;

    // ...
}

戻り値の検証 (応答以外)

通常のメソッドの戻り値 (応答以外) に検証を適用するには、メソッド署名の前にアノテーションを追加します。たとえば、nullness (@NotNull アノテーション) の戻り値をテストし、検証の制約を再帰的にテストするには (@Valid アノテーション)、以下のように getBook メソッドにアノテーションを付けます。

import javax.validation.constraints.NotNull;
import javax.validation.Valid;
...
@GET
@Path("/books/{bookId}")
@Override
@NotNull @Valid
public Book getBook(@PathParam("bookId") String id) {
    return new Book( id );
}

戻り値 (応答) の検証

javax.ws.rs.core.Response オブジェクトを返すメソッドに検証を適用するには、Response 以外のケースと同じアノテーションを使用できます。以下に例を示します。

import javax.validation.constraints.NotNull;
import javax.validation.Valid;
import javax.ws.rs.core.Response;
...
@GET
@Path("/books/{bookId}")
@Valid @NotNull
public Response getBookResponse(@PathParam("bookId") String id) {
    return Response.ok( new Book( id ) ).build();
}

65.2.2. 標準アノテーション

Bean 検証の制約

表65.1「Bean Validation の標準アノテーション」 は、Bean Validation 仕様で定義されている標準のアノテーションで、フィールドやメソッドの戻り値およびパラメーターの制約定義に使用できます (標準アノテーションはクラスレベルで適用できません)。

表65.1 Bean Validation の標準アノテーション

Annotation適用先説明

@AssertFalse

Booleanboolean

アノテーションが付けられた要素が false であることを確認します。

@AssertTrue

Booleanboolean

アノテーションが付けられた要素が true であることを確認します。

@DecimalMax(value=, inclusive=)

BigDecimalBigIntegerCharSequencebyteshortintlong、およびプリミティブ型ラッパー

inclusive=false の場合、アノテーションが付けられた値が指定された最大値を下回ることを確認します。そうでない場合は、値が指定の最大値以下であることを確認します。value パラメーターは、BigDecimal 文字列形式で最大値を指定します。

@DecimalMin(value=, inclusive=)

BigDecimalBigIntegerCharSequencebyteshortintlong、およびプリミティブ型ラッパー

inclusive=false の場合、アノテーションが付けられた値が指定された最小値を上回ることを確認します。そうでない場合は、値が指定の最小値以上であることを確認します。value パラメーターは BigDecimal 文字列形式で最小値を指定します。

@Digits(integer=, fraction=)

BigDecimalBigIntegerCharSequencebyteshortintlong、およびプリミティブ型ラッパー

アノテーションが付けられた値が、整数部の桁数が integer までで、小数部の桁数が fraction までの数値であるかどうかを確認します。

@Future

java.util.Date, java.util.Calendar

アノテーション付き日付が未来の日付であるかどうかを確認します。

@Max(value=)

BigDecimalBigIntegerCharSequencebyteshortintlong、およびプリミティブ型ラッパー

アノテーション付きの値が指定の最大値以下であるかを確認します。

@Min(value=)

BigDecimalBigIntegerCharSequencebyteshortintlong、およびプリミティブ型ラッパー

アノテーション付きの値が指定の最小値以上であるかを確認します。

@NotNull

任意のタイプ

アノテーションが付けられた値が null でないことを確認します。

@Null

任意のタイプ

アノテーションが付けられた値が null であることを確認します。

@Past

java.util.Date, java.util.Calendar

アノテーションが付けられた日付が過去のものであるかどうかを確認します。

@Pattern(regex=, flag=)

CharSequence

指定されたフラグの一致を考慮して、アノテーションが付けられた文字列が正規表現 regex に一致するかどうかをチェックします。

@Size(min=, max=)

CharSequenceCollectionMap、および配列

アノテーションが付けられたコレクション、マップ、または配列のサイズが min 以上 max 以下であるかどうかを確認します。

@Valid

プリミティブ以外のタイプ

注釈付きオブジェクトに対して再帰的に検証を実行します。オブジェクトがコレクションかアレイの場合は、要素は再帰的に検証されます。また、オブジェクトがマップの場合、値要素が再帰的に検証されます。

65.2.3. カスタムアノテーション

Hibernate でのカスタム制約の定義

Bean Validation API で独自のカスタム制約アノテーションを定義できます。Hibernate バリデーターの実装でこれを行う方法は、Hibernate Validator Reference GuideCreating custom constraints の章を参照してください。