第65章 Bean Validation
概要
Bean Validation は、Java 規格で、Java アノテーションをサービスクラスまたはインターフェイスに追加することでランタイム制約を定義できるようにします。Apache CXF はインターセプターを使用して、この機能を Web サービスメソッド呼び出しと統合します。
65.1. はじめに
概要
Bean Validation 1.1(JSR-349): 元の Bean Validation 1.0 (JSR-303) の後継であり、Java アノテーションを使用してランタイム時にチェックできる制約を宣言できます。アノテーションを使用して、Java コードの以下の部分に制約を定義できます。
- Bean クラスのフィールド。
- メソッドおよびコンストラクターパラメーター。
- メソッドの戻り値。
アノテーション付きクラスの例
以下の例は、標準の Bean Validation 制約がある、アノテーション付きの Java クラスです。
// Java import javax.validation.constraints.NotNull; import javax.validation.constraints.Max; import javax.validation.Valid; ... public class Person { @NotNull private String firstName; @NotNull private String lastName; @Valid @NotNull private Person boss; public @NotNull String saveItem( @Valid @NotNull Person person, @Max( 23 ) BigDecimal age ) { // ... } }
Bean Validation またはスキーマの検証
場合によっては、Bean Validation とスキーマ検証は非常に似ています。XML スキーマでのエンドポイント設定は、Web サービスエンドポイントでランタイム時にメッセージを検証するように適切に確立された方法です。XML スキーマは、受信および送信メッセージに対して、Bean Validation と同じ制約の多くを確認できます。しかし、Bean Validation は、以下のような理由で便利な代替手段となる場合があります。
- Bean Validation を使用すると、XML スキーマとは独立して制約を定義できる (コードファーストサービス開発の場合などに便利です)。
- 現在の XML スキーマが lax 以外の場合は、Bean Validation を使用してより厳密な制約を定義できる。
- Bean Validation を使用すると、カスタム制約を定義できますが、XML スキーマ言語を使用して定義できない場合があります。
依存関係
Bean Validation 1.1(JSR-349) 標準は、実装ではなく API のみを定義します。依存関係は、以下の 2 つの部分で指定する必要があります。
- コア依存関係 は、Bean Validation 1.1 API、Java 統合式言語 API および実装を提供します。
- Hibernate Validator の依存関係 は、Bean Validation 1.1 の実装を提供します。
コアの依存関係
Bean バリデーションを使用するには、以下のコア依存関係をプロジェクトの Maven pom.xml
ファイルに追加する必要があります。
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <!-- use 3.0-b02 version for Java 6 --> <version>3.0.0</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.el</artifactId> <!-- use 3.0-b01 version for Java 6 --> <version>3.0.0</version> </dependency>
javax.el/javax.el-api
および org.glassfish/javax.el
依存関係は、Java 統合式言語の API および実装を提供します。この式言語は、Bean Validation によって内部で使用されますが、アプリケーションプログラミングレベルでは重要ではありません。
Hibernate Validator の依存関係
Bean バリデーションの Hibernate Validator 実装を使用するには、以下の追加の依存関係をプロジェクトの Maven pom.xml
ファイルに追加します。
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.0.3.Final</version> </dependency>
OSGi 環境における検証プロバイダーの解決
検証プロバイダーを解決するデフォルトのメカニズムには、クラスパスをスキャンしてプロバイダーリソースを検索する必要があります。ただし、OSGi (Apache Karaf) 環境の場合、検証プロバイダー (Hibernate バリデーターなど) は別のバンドルにパッケージ化されているため、アプリケーションのクラスパスで自動的に使用できないため、このメカニズムは機能しません。OSGi のコンテキストでは、Hibernate バリデーターをアプリケーションバンドルに接続する必要があり、OSGi にはこれを正常に実行するためのサポートが若干必要です。
OSGi での検証プロバイダーの明示設定
OSGi のコンテキストでは、自動検出に依存するのではなく、検証プロバイダーを明示的に設定する必要があります。たとえば、共通の検証機能 (「Bean 検証機能」を参照) を使用して Bean Validation を有効にする場合は、以下のように検証プロバイダーで設定する必要があります。
<bean id="commonValidationFeature" class="org.apache.cxf.validation.BeanValidationFeature"> <property name="provider" ref="beanValidationProvider"/> </bean> <bean id="beanValidationProvider" class="org.apache.cxf.validation.BeanValidationProvider"> <constructor-arg ref="validationProviderResolver"/> </bean> <bean id="validationProviderResolver" class="org.example.HibernateValidationProviderResolver"/>
HibernateValidationProviderResolver
は、Hibernate 検証プロバイダーをラッピングするカスタムクラスです。
HibernateValidationProviderResolver クラスの例
以下のコード例は、Hibernate バリデーターを解決するカスタム HibernateValidationProviderResolver
を定義する方法を示しています。
// Java package org.example; import static java.util.Collections.singletonList; import org.hibernate.validator.HibernateValidator; import javax.validation.ValidationProviderResolver; import java.util.List; /** * OSGi-friendly implementation of {@code javax.validation.ValidationProviderResolver} returning * {@code org.hibernate.validator.HibernateValidator} instance. * */ public class HibernateValidationProviderResolver implements ValidationProviderResolver { @Override public List getValidationProviders() { return singletonList(new HibernateValidator()); } }
Maven バンドルプラグインを使用するように設定された Maven ビルドシステムに前述のクラスをビルドすると、アプリケーションはデプロイ時に Hibernate バリデーターバンドルに接続されます (Hibernate validator バンドルが OSGi コンテナーにデプロイされていることを前提とします)。