3

We have web service (jaxws) which is calling another web service (aslo jaxws). Jaxws client configuration looks like this --

 <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>

As you can see we have two interceptors and one fault listener. We want to communication among these interceptors, fault listeners and web service code. As given in SO THREAD, we used cxf Exchange object for communication between web service and interceptor.

Our inFaultInterceptor code look like this --

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

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

}

Out web service code look like this --

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

But, int the web service code we are getting null for given "key", means "key" is not present.

Is there any way in which we can communicate between interceptors and web service?

P.S : We are able to communicate within interceptors and listeners with the above method. That is, we are able to access key set in outInterceptor in inFaultInterceptor, but keys set in any interceptor or listener is not accessible in web service.

Community
  • 1
  • 1
Arun Rahul
  • 565
  • 1
  • 7
  • 24
  • `PhaseInterceptorChain` is using a `ThreadLocal` to store the message. Probably the Exchange Messsage is consumed and cleaned after interceptor chain finish and you can not recover it with `PhaseInterceptorChain.getCurrentMessage()` – pedrofb Jul 12 '16 at 05:54

1 Answers1

1

Not sure if there is any Cxf in built mechanism, I use ThreadLocal to pass information between webservice method and interceptor,

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();

     }

}

Interceptor class

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

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

And WebService Method.

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

NOTE:

  1. Once used you should explicitly clear the thread context else you would end up leaking memory
Karthik Prasad
  • 9,662
  • 10
  • 64
  • 112