Menu Close

第65章 Bean バリデーション

概要

Bean バリデーションは、Java アノテーションをサービスクラスまたはインターフェースに追加してランタイム制約の定義を可能にする Java 標準です。Apache CXF はインターセプターを使用して、この機能を Web サービスメソッド呼び出しと統合します。

65.1. はじめに

概要

Bean Validation 1.1 (JSR-349) は、元の Bean Validation 1.0 (JSR-303) の進化版であり、Java アノテーションを使用して、実行時に確認できる制約を宣言できます。アノテーションを使用して、Java コードの次の部分で制約を定義できます。

  • Bean クラスのフィールド
  • メソッドおよびコンストラクターのパラメーター
  • メソッド戻り値

アノテーションが付けられたクラスの例

以下の例は、いくつかの標準 Bean バリデーション制約でアノテーションが付けられた 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 バリデーションまたはスキーマバリデーション

いくつかの点で、Bean バリデーションとスキーマバリデーションは非常によく似ています。XML スキーマでエンドポイントを設定することは、Web サービスエンドポイントで実行時にメッセージを検証するための十分に確立された方法です。XML スキーマでは、受信メッセージや送信メッセージに対する Bean バリデーションと同じ制約の多くを確認できます。それにもかかわらず、Bean バリデーションは、次の 1 つ以上の理由で有用な代替手段となることがあります。

  • Bean バリデーションを使用すると、XML スキーマとは独立して制約を定義できます (たとえば、コードファーストサービスの開発の場合に役立ちます)。
  • 現在の XML スキーマが緩すぎる場合は、Bean バリデーションを使用してより厳密な制約を定義できます。
  • Bean バリデーションでは、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 バリデーションによって内部的に使用されますが、アプリケーションプログラミングレベルで重要ではありません。

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 validator など) は別のバンドルにパッケージ化され、アプリケーションクラスパスで自動的に利用できないため、このメカニズムは 動作 しません。OSGi のコンテキストでは、Hibernate バリデーターはアプリケーションバンドルに接続する必要があるため、OSGi はこれを正常に行うために若干のヘルプが必要です。

OSGi で検証プロバイダーを明示的に設定

OSGi のコンテキストでは、自動検出に依存する代わりに、検証プロバイダーを明示的に設定する必要があります。たとえば、共通の検証機能 (「Bean バリデーション機能」 を参照) を使用して Bean バリデーションを有効にするには、以下のように検証プロバイダーで設定する必要があります。

<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 コンテナーにデプロイされていることを前提とします)。