第60章 オンザフライでのインターセプターチェーンの操作
概要
インターセプターは、エンドポイントのインターセプターチェーンをメッセージ処理ロジックの一部として再設定できます。新しいインターセプターの追加、インターセプターの削除、インターセプターの並べ替え、インターセプターの一時停止などを行うことができます。すべてのオンザフライ操作は呼び出し固有であるため、エンドポイントがメッセージ交換に関与するたびに元のチェーンが使用されます。
概要
インターセプターチェーンは、その作成のきっかけとなったメッセージ交換の間だけ存続します。各メッセージには、メッセージを処理するインターセプターチェーンへの参照が含まれています。開発者は、この参照を使用してメッセージのインターセプターチェーンを変更できます。チェーンは交換ごとに行われるため、メッセージのインターセプターチェーンに加えられた変更は他のメッセージ交換には影響しません。
チェーンライフサイクル
インターセプターチェーンとチェーン内のインターセプターは、呼び出しごとにインスタンス化されます。メッセージ交換に参加するエンドポイントが呼び出されると、必要なインターセプターチェーンがそのインターセプターのインスタンスと共にインスタンス化されます。インターセプターチェーンの作成の原因となったメッセージエクスチェンジが完了すると、チェーンとそのインターセプターインスタンスが破棄されます。
つまり、インターセプターチェーンまたはインターセプターのフィールドへの変更は、別のメッセージ交換には永続されません。そのため、インターセプターが別のインターセプターをアクティブなチェーンに配置すると、アクティブなチェーンのみが有効になります。今後のメッセージ交換は、エンドポイントの設定によって決定される、初期の状態から作成されます。また、開発者は今後のメッセージ処理を変更するインターセプターにフラグを設定できなくなります。
インターセプターが今後のインスタンスに情報を渡す必要がある場合は、メッセージコンテキストにプロパティーを設定できます。コンテキストは、メッセージエクスチェンジ全体で保持されます。
インターセプターチェーンの取得
メッセージのインターセプターチェーンを変更する最初のステップはインターセプターチェーンを取得します。これは、例60.1「インターセプターチェーンを取得するメソッド」 に記載されている Message.getInterceptorChain()
メソッドを使用して行われます。インターセプターチェーンは org.apache.cxf.interceptor.InterceptorChain オブジェクトとして返されます。
例60.1 インターセプターチェーンを取得するメソッド
InterceptorChain
getInterceptorChain
インターセプターの追加
例60.2「インターセプターチェーンにインターセプターを追加するメソッド」 にあるように、InterceptorChain オブジェクトには、インターセプターチェーンにインターセプターを追加するためのメソッドが 2 つあります。1 つは単一のインターセプターを追加でき、もう 1 つは複数のインターセプターを追加できます。
例60.2 インターセプターチェーンにインターセプターを追加するメソッド
add
Interceptor<? extends Message>
i
add
Collection<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 インターセプターチェーンからインターセプターを削除するメソッド
remove
Interceptor<? 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
は、チェーンから削除するインターセプターのクラス名です。