CXF拦截器、监听器和Web服务(JAX-WS)之间的通信

3
我们有一个 Web 服务(jaxws),它调用另一个 Web 服务(也是 jaxws)。Jaxws 客户端配置如下--
 <jaxws:client id="helloClient"
              serviceClass="demo.spring.HelloWorld"
              address="http://localhost:9002/HelloWorld" >
      <jaxws:outInterceptors>
             <bean class="com.company.MyOutInterceptor"/>
      </jaxws:outInterceptors>
      <jaxws:inFaultInterceptors>
             <bean class="com.company.MyInFaultInterceptor"/>
      </jaxws:inFaultInterceptors>
      <cxf:properties>
             <entry key="org.apache.cxf.logging.FaultListener">
                 <bean class="com.company.MyFaultListener"/>
             </entry>
      </cxf:properties>
 </jaxws:client>

如您所见,我们有两个拦截器和一个故障侦听器。我们希望在这些拦截器、故障侦听器和 Web 服务代码之间进行通信。
根据 SO THREAD,我们使用了 CXF 的 Exchange 对象来实现 Web 服务和拦截器之间的通信。
我们的 inFaultInterceptor 代码如下:
public class MyInFaultInterceptor extends AbstractPhaseInterceptor<Message>      {
      public MyInFaultInterceptor() {
           super(Phase.RECEIVE);
      }

      public void handleMessage(Message message) {
          message.getExchange().put("key", "value");
      }

我们的web服务代码如下--

我们的web服务代码看起来像这样--

public String addNumbers(int a, int b){
     try{
          myService.add(a,b);
     }catch(MyServiceException e){
          //Logging
     }
     Object value = PhaseInterceptorChain.getCurrentMessage().getExchange().get("key");
}  

但是,在Web服务代码中,我们得到了给定的“key”的空值,这意味着“key”不存在。

有没有办法在拦截器和Web服务之间进行通信?

P.S:我们能够通过上述方法在拦截器和监听器之间进行通信。也就是说,在inFaultInterceptor中可以访问outInterceptor中设置的密钥,但是在任何拦截器或监听器中设置的密钥都无法访问Web服务。


PhaseInterceptorChain 使用 ThreadLocal 存储消息。很可能在拦截器链完成后,交换消息被消耗和清理,因此您无法使用 PhaseInterceptorChain.getCurrentMessage() 恢复它。 - pedrofb
1个回答

1

不确定是否有任何内置的Cxf机制,我使用ThreadLocal在Web服务方法和拦截器之间传递信息。

public final class KPContextHolder {

    private static ThreadLocal<String> myKey = new ThreadLocal<>();

    private KPContextHolder() {

    }

    public static String getMyKey() {
        return myKey.get();
    }

    public static void setMyKey(final String input) {
        myKey.set(input);
    }

    /**
     * Clear all the fields saved in the thread context
     */
    public static void clear() {
        myKey.remove();

     }

}

拦截器类
  public class MyInFaultInterceptor extends AbstractPhaseInterceptor<Message>      {
          public MyInFaultInterceptor() {
               super(Phase.RECEIVE);
          }

          public void handleMessage(Message message) {
              KPContextHolder.setMyKey("value");
          }
}

和 WebService 方法。

public String addNumbers(int a, int b){
     try{
          myService.add(a,b);
     }catch(MyServiceException e){
          //Logging
     }
     String value = KPContextHolder.getMyKey();
} 

注意:

  1. 一旦使用,您应该明确清除线程上下文,否则会导致内存泄漏。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接