This article shows how to use Apache CXF interceptors as an alternative to JAX-WS handlers for your CXF-based web service providers and SOAP clients. The finished tutorial source code can be downloaded or cloned from GitHub.
Prior to beginning with CXF interceptors, if your goal is just to modify the SOAP requests and/or responses, check the Additional Resources section at the bottom of this blog entry. It lists simpler alternatives to working with CXF interceptors that might also accomplish what you're looking for.
Interceptor architectural overview
Apache CXF internally uses constructs called interceptors and interceptor chains in its processing of SOAP requests and responses. An interceptor chain is a sequence of interceptors, activated by CXF's PhaseInterceptorChain class, each of which processes a SOAP message in the manner of the Pipes and Filters messaging pattern. There are six such chains, although not all will be activated for every SOAP request/response:
A simple way to become acquainted with configuring interceptors is to activate logging of SOAP requests and/or responses, a process which is handled in CXF by interceptors. To learn how to program your own interceptors, the CXF source for its many internal interceptors is an excellent resource -- they can be searched for individually in the repository search box on the CXF GitHub home page.
Similarities and Differences between JAX-WS Handlers and CXF Interceptors
JAX-WS handlers are internally implemented in CXF by use of interceptors, so anything that can be done with the former can be done with the latter. Handlers and interceptors have strong similarities in that both have
handleFault() methods where needed processing can be added. Both provide mechanisms for SOAP messages as well as more generic XML over HTTP routing. The routing direction is also similar in that handleFault(), when errors occur, causes the interceptors to run in reverse order.
close()method (used for object cleanup) is available with handlers but not interceptors.
ProtocolException(or a subclass), while Interceptors use
Important APIs for the JAX-WS handler objects:
|Handler Type||Handler Class||Message Context||Message Class|
|Logical Handler (SOAP body without header or basic XML over HTTP)||LogicalHandler||LogicalMessageContext||LogicalMessage|
|(SOAP) Protocol Handler (full SOAP envelope including header)||SOAPHandler||SOAPMessageContext||SOAPMessage|
Approximate equivalents for the CXF interceptors:
|Interceptor Type||Interceptor Class||Message Class|
|Logical Interceptors||AbstractPhaseInterceptor||Message (XMLMessage a possible option)|
The main internal CXF classes which handle the interceptor Message to JAX-WS handler MessageContext translation are WrappedMessageContext, AbstractJAXWSMethodInvoker, JAXWSMethodInvoker, and JaxWsClientProxy.
Using CXF interceptors in place of JAX-WS handlers
Follow along the JAX-WS Handler tutorial for this process, except replace certain steps as shown below:
Skip Step #2 (HandlerUtils.java class), as it is handler-specific.
For Step #3, use the following interceptors class instead:
Although we're using SAAJ above to add SOAP headers JAXB may be also be available for you--see this example.
For Step #4, Use the following SOAP client:
For Step #5, Use the following service interceptor classes in the
service subproject instead:
For Step #6, use the following web service provider:
Step #7 can be skipped because I'm using annotations above to add the service-side interceptors--see here for alternative XML file configuration.
Working With Phases
The phases that your interceptors are attached to, as well as the ordering of interceptors within phases, are important for the successful execution of SOAP calls and responses. It can take some trial and error to determine this information for each of your interceptors. Some general advice: