Menu Close

第60章 実行時のインターセプターチェーンの操作

概要

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

概要

インターセプターチェーンは、その作成を引き起こしたメッセージエクスチェンジが存在する期間のみ存在します。各メッセージには、処理を行うインターセプターチェーンへの参照が含まれます。開発者は、この参照を使用してメッセージのインターセプターチェーンを変更できます。チェーンはエクスチェンジ単位であるため、メッセージのインターセプターチェーンに加えられた変更は、他のメッセージエクスチェンジには影響しません。

チェーンのライフサイクル

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

つまり、インターセプターチェーンまたはインターセプターのフィールドに加えられた変更は、メッセージエクスチェンジ全体で永続化されないことになります。そのため、インターセプターがアクティブなチェーンに別のインターセプターを配置すると、アクティブなチェーンだけが影響します。その後のメッセージエクスチェンジは、エンドポイントの設定によって決定される元の状態から作成されます。また、開発者は、その後のメッセージ処理を変更するインターセプターにフラグを設定できないことを意味します。

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

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

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

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

InterceptorChaingetInterceptorChain

インターセプターの追加

インターセプターをインターセプターチェーンに追加するため、InterceptorChain オブジェクトには 例60.2「インターセプターをインターセプターチェーンに追加するメソッド」 で説明されている 2 つのメソッドがあります。1 つは 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「インターセプターをその場でインターセプターチェーンに追加」 のコードは、以下を行います。

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

重要

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

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

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

インターセプターの削除

例60.4「インターセプターチェーンからインターセプターを削除するメソッド」 の説明にあるように、InterceptorChain オブジェクトには、インターセプターチェーンからインターセプターを削除するためのメソッドが 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 は、チェーンから削除するインターセプターのクラス名に置き換えます。