第60章 オンザフライでのインターセプターチェーンの操作

概要

インターセプターは、エンドポイントのインターセプターチェーンをメッセージ処理ロジックの一部として再設定できます。新しいインターセプターの追加、インターセプターの削除、インターセプターの並べ替え、インターセプターの一時停止などを行うことができます。すべてのオンザフライ操作は呼び出し固有であるため、エンドポイントがメッセージ交換に関与するたびに元のチェーンが使用されます。

概要

インターセプターチェーンは、その作成のきっかけとなったメッセージ交換の間だけ存続します。各メッセージには、メッセージを処理するインターセプターチェーンへの参照が含まれています。開発者は、この参照を使用してメッセージのインターセプターチェーンを変更できます。チェーンは交換ごとに行われるため、メッセージのインターセプターチェーンに加えられた変更は他のメッセージ交換には影響しません。

チェーンライフサイクル

インターセプターチェーンとチェーン内のインターセプターは、呼び出しごとにインスタンス化されます。メッセージ交換に参加するエンドポイントが呼び出されると、必要なインターセプターチェーンがそのインターセプターのインスタンスと共にインスタンス化されます。インターセプターチェーンの作成の原因となったメッセージエクスチェンジが完了すると、チェーンとそのインターセプターインスタンスが破棄されます。

つまり、インターセプターチェーンまたはインターセプターのフィールドへの変更は、別のメッセージ交換には永続されません。そのため、インターセプターが別のインターセプターをアクティブなチェーンに配置すると、アクティブなチェーンのみが有効になります。今後のメッセージ交換は、エンドポイントの設定によって決定される、初期の状態から作成されます。また、開発者は今後のメッセージ処理を変更するインターセプターにフラグを設定できなくなります。

インターセプターが今後のインスタンスに情報を渡す必要がある場合は、メッセージコンテキストにプロパティーを設定できます。コンテキストは、メッセージエクスチェンジ全体で保持されます。

インターセプターチェーンの取得

メッセージのインターセプターチェーンを変更する最初のステップはインターセプターチェーンを取得します。これは、例60.1「インターセプターチェーンを取得するメソッド」 に記載されている Message.getInterceptorChain() メソッドを使用して行われます。インターセプターチェーンは org.apache.cxf.interceptor.InterceptorChain オブジェクトとして返されます。

例60.1 インターセプターチェーンを取得するメソッド

InterceptorChaingetInterceptorChain

インターセプターの追加

例60.2「インターセプターチェーンにインターセプターを追加するメソッド」 にあるように、InterceptorChain オブジェクトには、インターセプターチェーンにインターセプターを追加するためのメソッドが 2 つあります。1 つは単一のインターセプターを追加でき、もう 1 つは複数のインターセプターを追加できます。

例60.2 インターセプターチェーンにインターセプターを追加するメソッド

addInterceptor<? extends Message>iaddCollection<Interceptor<? extends Message>>i

例60.3「オンザフライでのインターセプターチェーンへのインターセプターの追加」 は、メッセージのインターセプターチェーンに単一のインターセプターを追加するためのコードです。

例60.3 オンザフライでのインターセプターチェーンへのインターセプターの追加

void handleMessage(Message message)
{
  ...
  AddledIntereptor addled = new AddledIntereptor();
  InterceptorChain chain = message.getInterceptorChain();
  chain.add(addled);
  ...
}

例60.3「オンザフライでのインターセプターチェーンへのインターセプターの追加」 のコードは、以下を行います。

チェーンに追加するインターセプターのコピーをインスタンス化します。

重要

チェーンに追加されるインターセプターは、現在のインターセプターと同じフェーズか、現在のインターセプターよりも後続フェーズのいずれかである必要があります。

現在のメッセージのインターセプターチェーンを取得します。

新しいインターセプターをチェーンに追加します。

インターセプターの削除

InterceptorChain オブジェクトには、例60.4「インターセプターチェーンからインターセプターを削除するメソッド」 にあるように、インターセプターチェーンからインターセプターを削除するためのメソッドが 1 つあります。

例60.4 インターセプターチェーンからインターセプターを削除するメソッド

removeInterceptor<? extends Message>i

例60.5「オンザフライでのインターセプターチェーンからのインターセプターの削除」 は、メッセージのインターセプターチェーンからインターセプターを削除するコードです。

例60.5 オンザフライでのインターセプターチェーンからのインターセプターの削除

void handleMessage(Message message)
{
  ...
  Iterator<Interceptor<? extends Message>> iterator =
            message.getInterceptorChain().iterator();
  Interceptor<?> removeInterceptor =  null;
  for (; iterator.hasNext(); ) {
    Interceptor<?> interceptor = iterator.next();
    if (interceptor.getClass().getName().equals("InterceptorClassName")) {
      removeInterceptor = interceptor;
      break;
    }
  }

  if (removeInterceptor !=  null) {
    log.debug("Removing interceptor {}",removeInterceptor.getClass().getName());
    message.getInterceptorChain().remove(removeInterceptor);
  }
  ...
}

ここで、InterceptorClassName は、チェーンから削除するインターセプターのクラス名です。