59.3. プログラムによるインターセプターの追加

59.3.1. インターセプターの追加方法

インターセプターは、以下のいずれかの方法を使用してプログラム的にエンドポイントに割り当てることができます。

  • InterceptorProvider API
  • Java アノテーション

InterceptorProvider API を使用すると、開発者はインターセプターチェーンを持つ任意のランタイムコンポーネントにインターセプターを割り当てることができますが、基礎となる Apache CXF クラスを使用する必要があります。Java アノテーションはサービスインターフェイスまたはサービス実装にのみ追加できますが、開発者は JAX-WS API または JAX-RS API 内だけで作業を行えるようにできます。

59.3.2. インターセプタープロバイダー API の使用

概要

インターセプターは、インターセプタープロバイダーインターフェイス に示されている InterceptorProvider インターフェイスを実装するコンポーネントであればどれでも登録できます。

インターセプタープロバイダーインターフェイス

package org.apache.cxf.interceptor;

import java.util.List;

public interface InterceptorProvider
{
    List<Interceptor<? extends Message>> getInInterceptors();

    List<Interceptor<? extends Message>> getOutInterceptors();

    List<Interceptor<? extends Message>> getInFaultInterceptors();

    List<Interceptor<? extends Message>> getOutFaultInterceptors();
}

インターフェイスの 4 つのメソッドにより、エンドポイントのインターセプターチェーンを Java List オブジェクトとして取得できます。Java List オブジェクトによって提供されるメソッドを使用することで、開発者は任意のチェーンにインターセプターを追加および削除できます。

手順

InterceptorProvider API を使用してインターセプターをランタイムコンポーネントのインターセプターチェーンに割り当てるには、以下を実行する必要があります。

  1. インターセプターが割り当てられるチェーンを使用してランタイムコンポーネントへのアクセスを取得します。

    開発者は、Apache CXF 固有の API を使用して標準の Java アプリケーションコードからランタイムコンポーネントにアクセスする必要があります。ランタイムコンポーネントは通常、JAX-WS または JAX-RS アーティファクトを基盤の Apache CXF オブジェクトにキャストすることでアクセスできます。

  2. インターセプターのインスタンスを作成します。
  3. 適切な get メソッドを使用して、目的のインターセプターチェーンを取得します。
  4. List オブジェクトの add() メソッドを使用してインターセプターをインターセプターチェーンにアタッチします。

    通常、このステップはインターセプターチェーンの取得と組み合わされます。

インターセプターをコンシューマーに取り付け

プログラムでコンシューマーにインターセプターを取り付け は、JAX-WS コンシューマーのインバウンドインターセプターチェーンにインターセプターを割り当てるコードです。

プログラムでコンシューマーにインターセプターを取り付け

package com.fusesource.demo;

import java.io.File;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import org.apache.cxf.endpoint.Client;

public class Client
{
  public static void main(String args[])
  {
    QName serviceName = new QName("http://demo.eric.org", "stockQuoteReporter");
    Service s = Service.create(serviceName);

    QName portName = new QName("http://demo.eric.org", "stockQuoteReporterPort");
    s.addPort(portName, "http://schemas.xmlsoap.org/soap/", "http://localhost:9000/EricStockQuote");

    quoteReporter proxy = s.getPort(portName, quoteReporter.class);

    Client cxfClient = (Client) proxy;

    ValidateInterceptor validInterceptor = new ValidateInterceptor();
    cxfClient.getInInterceptor().add(validInterceptor);

    ...
  }
}

プログラムでコンシューマーにインターセプターを取り付け のコードは、以下を行います。

コンシューマーの JAX-WS Service オブジェクトを作成します。

コンシューマーのターゲットアドレスを提供する Service オブジェクトにポートを追加します。

サービスプロバイダーでメソッドを呼び出すために使用されるプロキシーを作成します。

プロキシーを org.apache.cxf.endpoint.Client 型にキャストします。

インターセプターのインスタンスを作成します。

インターセプターをインバウンドインターセプターチェーンに割り当てます。

インターセプターのサービスプロバイダーへの割り当て

プログラムを使用したインターセプターのサービスプロバイダーへの割り当て は、サービスプロバイダーのアウトバウンドインターセプターチェーンにインターセプターを割り当てるコードです。

プログラムを使用したインターセプターのサービスプロバイダーへの割り当て

package com.fusesource.demo;
import java.util.*;

import org.apache.cxf.endpoint.Server;
import org.apache.cxf.frontend.ServerFactoryBean;
import org.apache.cxf.frontend.EndpointImpl;

public class stockQuoteReporter implements quoteReporter
{
  ...
  public stockQuoteReporter()
  {
    ServerFactoryBean sfb = new ServerFactoryBean();
    Server server = sfb.create();
    EndpointImpl endpt = server.getEndpoint();

    AuthTokenInterceptor authInterceptor = new AuthTokenInterceptor();

    endpt.getOutInterceptor().add(authInterceptor);
  }
}

プログラムを使用したインターセプターのサービスプロバイダーへの割り当て のコードは、以下を行います。

基盤となる Apache CXF オブジェクトへのアクセスを提供する ServerFactoryBean オブジェクトを作成します。

Apache CXF がエンドポイントを表すために使用する Server オブジェクトを取得します。

サービスプロバイダーの Apache CXF EndpointImpl オブジェクトを取得します。

インターセプターのインスタンスを作成します。

エンドポイントのアウトバウンドインターセプターチェーンにインターセプターを割り当てます。

バスへのインターセプターの取り付け

バスへのインターセプターの取り付け は、バスのインバウンドインターセプターチェーンにインターセプターを割り当てるコードです。

バスへのインターセプターの取り付け

import org.apache.cxf.BusFactory;
org.apache.cxf.Bus;

...

Bus bus = BusFactory.getDefaultBus();

WatchInterceptor watchInterceptor = new WatchInterceptor();

bus..getInInterceptor().add(watchInterceptor);

...

バスへのインターセプターの取り付け のコードは、以下を行います。

ランタイムインスタンスのデフォルトのバスを取得します。

インターセプターのインスタンスを作成します。

インターセプターをインバウンドインターセプターチェーンに割り当てます。

WatchInterceptor は、ランタイムインスタンスによって作成されるすべてのエンドポイントのインバウンドインターセプターチェーンにアタッチされます。

59.3.3. Java アノテーションの使用

概要

Apache CXF は、開発者がエンドポイントによって使用されるインターセプターチェーンを指定できるように、4 つの Java アノテーションを提供します。インターセプターをエンドポイントに割り当てる他の手段とは異なり、アノテーションはアプリケーションレベルのアーティファクトに割り当てられます。使用するアーティファクトにより、アノテーションの影響範囲が決まります。

アノテーションを配置する場所

アノテーションは以下のアーティファクトに配置できます。

  • エンドポイントを定義するサービスエンドポイントインターフェイス (SEI)

    アノテーションが SEI に配置されると、インターフェイスを実装するサービスプロバイダーすべてと、プロキシーの作成に SEI を使用するコンシューマーすべてに影響があります。

  • サービス実装クラス

    アノテーションが実装クラスに配置されると、実装クラスを使用するすべてのサービスプロバイダーが影響を受けます。

アノテーション

アノテーションはすべて org.apache.cxf.interceptor パッケージにあり、表59.2「インターセプターチェーンアノテーション」 で説明されています。

表59.2 インターセプターチェーンアノテーション

Annotation説明

InInterceptors

インバウンドインターセプターチェーンのインターセプターを指定します。

OutInterceptors

アウトバウンドインターセプターチェーンのインターセプターを指定します。

InFaultInterceptors

インバウンドフォールトインターセプターチェーンのインターセプターを指定します。

OutFaultInterceptors

アウトバウンド障害インターセプターチェーンのインターセプターを指定します。

インターセプターの一覧表示

インターセプターの一覧は、チェーンアノテーションでインターセプターを一覧表示する構文 に記載されている構文を使用して、完全修飾クラス名のリストとして指定されます。

チェーンアノテーションでインターセプターを一覧表示する構文

interceptors={"interceptor1", "interceptor2", ..., "interceptorN"}

サービス実装へのインターセプターの割り当て は、SayHiImpl によって提供されるロジックを使用するエンドポイントのインバウンドインターセプターチェーンに 2 つのインターセプターをアタッチするアノテーションを示しています。

サービス実装へのインターセプターの割り当て

import org.apache.cxf.interceptor.InInterceptors;

@InInterceptors(interceptors={"com.sayhi.interceptors.FirstLast", "com.sayhi.interceptors.LogName"})
public class SayHiImpl implements SayHi
{
  ...
}