You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

Interceptors and Phases

Interceptors are the fundamental processing unit inside CXF. When a service is invoked, an InterceptorChain is created and invoked. Each interceptor gets a chance to do what they want with the message. This can include reading it, transforming it, processing headers, validating the message, etc.

Interceptors are relevant for both CXF clients and CXF servers. When a CXF client invokes a CXF server, there is an outgoing interceptor chain for the client and an incoming chain for the server. When the server sends the response back to the client, there is an outgoing chain for the server and an incoming one for the client.

Some examples of interceptors inside CXF include:

  • SoapActionInterceptor - Processes the SOAPAction header and selects an operation if its set.
  • StaxInInterceptor - Creates a Stax XMLStreamReader from the transport input stream.
  • Attachment(In/Out)Interceptor - Turns a multipart/related message into a series of attachments.

InterceptorChains are divided up into Phases. Each phase contains many interceptors. On the incoming chains, you'll have the following phases:

Phase

Functions

RECEIVE

Transport level processing

(PRE/USER/POST)_STREAM

Stream level processing/transformations

READ

This is where header reading typically occurs.

(PRE/USER/POST)_PROTOCOL

Protocol processing, such as JAX-WS SOAP handlers

UNMARSHAL

Unmarshalling of the request

(PRE/USER/POST)_LOGICAL

Processing of the umarshalled request

PRE_INVOKE

Pre invocation actions

INVOKE

Invocation of the service

POST_INVOKE

Invocation of the outgoing chain if there is one

On the outgoing chain there are the following phases:

Phase

Functions

SETUP

Any set up for the following phases

(PRE/USER/POST)_LOGICAL

Processing of objects about to marshalled

PREPARE_SEND

Opening of the connection

PRE_STREAM

 

PRE_PROTOCOL

Misc protocol actions.

WRITE

Writing of the protocol message, such as the SOAP Envelope.

MARSHAL

Marshalling of the objects

(USER/POST)_PROTOCOL

Processing of the protocol message.

(USER/POST)_STREAM

Processing of the byte level message

SEND

Final sending of message and closing of transport stream

InterceptorProviders

Several different components inside CXF may provide interceptors to an InterceptorChain. These implement the InterceptorProvider interface:

public interface InterceptorProvider {
    
    List<Interceptor> getInInterceptors();
    
    List<Interceptor> getOutInterceptors();
    
    List<Interceptor> getOutFaultInterceptors();
    
    List<Interceptor> getInFaultInterceptors();
}

To get an interceptor added to the interceptor chain, you'll want to add it to one of the Interceptor Providers.

MyInterceptor interceptor = new MyInterceptor();
provider.getInInterceptors().add(interceptor);

There are main InterceptorProviders inside CXF are:

  • Client
  • Endpoint
  • Service
  • Bus
  • Binding

Writing an Interceptor

Writing an interceptor is relatively simple. The best way to do this is to extend from an abstract class.

Practically speaking, there are two base classes you will be concerned with. The first is the AbstractPhaseInterceptor. The second is AbstractSoapInterceptor. The only difference between the two is that the latter will give you a SoapMessage instead of just a Message class. This allows you to access the SOAP headers and version.

Here is a small example of how to write a Soap interceptor:

public class MySoapInterceptor extends AbstractSoapInterceptor {
  public MySoapInterceptor () {
    super(Phase.PRE_PROTOCOL);
  }

  public MySoapInterceptor (String phase) {
    super(phase);
  }

  public void handleMessage(SoapMessage msg) throws SoapFault {
    System.out.println("Hello World!");
  }
}

To add this to your server, you'll want to get access to the Server object (see here for more info):

MySoapInterceptor myInterceptor = new MySoapInterceptor();

Server server = serverFactoryBean.create();
server.getEndpoint().getInInterceptor().add(myInterceptor);

On the Client side the process is very similar:

FooService client = ... ; // created from ClientProxyFactoryBean or generated JAX-WS client
MySoapInterceptor myInterceptor = new MySoapInterceptor();

Client cxfClient = ClientProxy.getClient(client);
cxfClient .getInInterceptor().add(myInterceptor);

You may also want to specify what phase your interceptor is in. To do this, you can simply set the phase:

public class MySoapInterceptor extends AbstractSoapInterceptor {
  public MySoapInterceptor() {
    super(Phase.USER_PROTOCOL);
  }
  ...
}

You can also express that you would like your interceptor to run before/after certain other interceptors in the same phase:

public class MySoapInterceptor extends AbstractSoapInterceptor {
  public MySoapInterceptor() {
    super(Phase.USER_PROTOCOL);
    getAfter().add(SomeOtherInterceptor.class.getName());
  }
  ...
}
  • No labels