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