【问题标题】:Communication between cxf interceptors, listeners and webservice (jaxws)cxf 拦截器、监听器和 webservice (jaxws) 之间的通信
【发布时间】:2023-03-18 21:37:01
【问题描述】:

我们有 Web 服务 (jaxws),它正在调用另一个 Web 服务 (aslo 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服务代码是这样的——

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”,我们得到 null,这意味着“key”不存在。

有什么方法可以在拦截器和拦截器之间进行通信 网络服务?

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

【问题讨论】:

  • PhaseInterceptorChain 使用ThreadLocal 来存储消息。可能在拦截器链完成后交换消息被消耗和清理,您无法使用PhaseInterceptorChain.getCurrentMessage() 恢复它

标签: java web-services cxf jax-ws interceptor


【解决方案1】:

不确定内置机制是否有Cxf,我使用ThreadLocal在webservice方法和拦截器之间传递信息,

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. 一旦使用,您应该显式清除线程上下文,否则最终会导致内存泄漏

【讨论】:

    猜你喜欢
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    • 2017-01-22
    • 1970-01-01
    • 2017-08-02
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多