Search code examples
javaspringjax-wscxfjax-rs

Apache CXF interceptor configuration


I created a SOAP interceptor as described in CXF docs:

public class SoapMessageInterceptor extends AbstractSoapInterceptor {
    public SoapMessageInterceptor() {
        super(Phase.USER_PROTOCOL);
    }
    public void handleMessage(SoapMessage soapMessage) throws Fault {
        // ...
    }
}

and registered it with the bus in Spring's application context:

  <cxf:bus>
    <cxf:inInterceptors>
      <ref bean="soapMessageInterceptor"/>
    </cxf:inInterceptors>
  </cxf:bus>

  <jaxws:endpoint id="customerWebServiceSoap"
        implementor="#customerWebServiceSoapEndpoint"
        address="/customerService"/>

All was working fine until I added a REST service:

  <jaxrs:server id="customerWebServiceRest" address="/rest">
    <jaxrs:serviceBeans>
      <ref bean="customerWebServiceRestEndpoint" />
    </jaxrs:serviceBeans>
  </jaxrs:server>

The problems is that the SOAP interceptor is now being triggered on REST requests also, which results in a class cast exception when the REST service is invoked.

<ns1:XMLFault xmlns:ns1="http://cxf.apache.org/bindings/xformat">
  <ns1:faultstring xmlns:ns1="http://cxf.apache.org/bindings/xformat">
    java.lang.ClassCastException: org.apache.cxf.message.XMLMessage
    cannot be cast to org.apache.cxf.binding.soap.SoapMessage
  </ns1:faultstring>
</ns1:XMLFault>

Is there any way to restrict the interceptor to SOAP messages only through configuration?

Update

Looks like I missed the page in the docs that describes this. Scroll down to Difference between JAXRS filters and CXF interceptors


Solution

  • You can attach interceptors to an individual endpoint rather than to the bus:

    <jaxws:endpoint id="customerWebServiceSoap"
        implementor="#customerWebServiceSoapEndpoint"
        address="/customerService">
      <jaxws:inInterceptors>
        <ref bean="soapMessageInterceptor"/>
      </jaxws:inInterceptors>
    </jaxws:endpoint>