第 60 章 在 Fly 操作拦截器链
摘要
拦截器可以重新配置端点的拦截器链,作为其消息处理逻辑的一部分。它可以添加新的拦截器、删除拦截器、重新排序拦截器,甚至挂起拦截器链。任何针对的操作都特定于调用,因此每次在消息交换中涉及端点时,都会使用原始链。
概述
拦截器链仅在创建消息交换时才有效。每个消息都包含对负责处理它的拦截器链的引用。开发人员可以使用此引用来更改消息的拦截器链。由于链是每个交换的,对消息的拦截器链所做的任何更改都不会影响其他消息交换。
链生命周期
拦截器链和链中的拦截器会根据每个调用进行实例化。当调用端点以参与消息交换时,所需的拦截器链会与其拦截器的实例一起实例化。当完成导致创建拦截器链的消息交换时,链及其拦截器实例将被销毁。
这意味着,您对拦截器链或拦截器字段所做的任何更改都不会在消息交换之间保留。因此,如果拦截器仅在活跃的链中放置另一个拦截器,则只有活跃的链生效。未来任何消息交换都将从 pristine 状态创建,具体由端点的配置决定。它还意味着,开发人员无法在拦截器中设置标记,该标志会改变将来的消息处理。
如果拦截器需要与将来的实例一起传递信息,可以在消息上下文中设置属性。该上下文在消息交换之间有效。
获取拦截器链
更改消息的拦截器链的第一步是获取拦截器链。这可以通过在 例 60.1 “获取拦截器链的方法” 中显示的 Message.getInterceptorChain ()
方法完成。拦截器链返回为 org.apache.cxf.interceptor.InterceptorChain 对象。
例 60.1. 获取拦截器链的方法
InterceptorChain
getInterceptorChain
添加拦截器
InterceptorChain 对象有两个方法,如 例 60.2 “将拦截器添加到拦截器链的方法” 所示,用于将拦截器添加到拦截器链。一个允许您添加单个拦截器,另一个允许您添加多个拦截器。
例 60.2. 将拦截器添加到拦截器链的方法
添加
Interceptor<? extends Message>
i
add
Collection<Interceptor<? extends Message>>
i
例 60.3 “将拦截器添加到拦截器链(on-the-fly)链” 显示将单个拦截器添加到消息的拦截器链的代码。
例 60.3. 将拦截器添加到拦截器链(on-the-fly)链
void handleMessage(Message message) { ... AddledIntereptor addled = new AddledIntereptor(); InterceptorChain chain = message.getInterceptorChain(); chain.add(addled); ... }
例 60.3 “将拦截器添加到拦截器链(on-the-fly)链” 中的代码执行以下操作:
实例化要添加到链中的拦截器副本。
添加到链的拦截器应位于与当前拦截器相同的阶段或后一个阶段,而不是当前的拦截器。
获取当前消息的拦截器链。
向链中添加新的拦截器。
删除拦截器
InterceptorChain 对象有一个方法,如 例 60.4 “从拦截器链中删除拦截器的方法” 所示,用于从拦截器链中删除拦截器。
例 60.4. 从拦截器链中删除拦截器的方法
删除
Interceptor<? extends Message>
i
例 60.5 “从拦截器链(on-the-fly)中删除拦截器” 显示从消息的拦截器链中删除拦截器的代码。
例 60.5. 从拦截器链(on-the-fly)中删除拦截器
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
是您要从链中删除的拦截器的类名称。