57.3. Adding interceptors programmatically

57.3.1. Approaches to Adding Interceptors

Interceptors can be attached to endpoints programmatically using either one of two approaches:
  • the InterceptorProvider API
  • Java annotations
Using the InterceptorProvider API allows the developer to attach interceptors to any of the runtime components that have interceptor chains, but it requires working with the underlying Apache CXF classes. The Java annotations can only be added to service interfaces or service implementations, but they allow developers to stay within the JAX-WS API or the JAX-RS API.

57.3.2. Using the interceptor provider API

Overview

Interceptors can be registered with any component that implements the InterceptorProvider interface shown in Example 57.3, “The interceptor provider interface”.

Example 57.3. The interceptor provider interface

package org.apache.cxf.interceptor;

import java.util.List;

public interface InterceptorProvider
{
    List<Interceptor<? extends Message>> getInInterceptors();
    
    List<Interceptor<? extends Message>> getOutInterceptors();
    
    List<Interceptor<? extends Message>> getInFaultInterceptors();

    List<Interceptor<? extends Message>> getOutFaultInterceptors();
}
The four methods in the interface allow you to retrieve each of an endpoint's interceptor chains as a Java List object. Using the methods offered by the Java List object, developers can add and remove interceptors to any of the chains.

Procedure

To use the InterceptorProvider API to attach an interceptor to a runtime component's interceptor chain, you must:
  1. Get access to the runtime component with the chain to which the interceptor is being attached.
    Developers must use Apache CXF specific APIs to access the runtime components from standard Java application code. The runtime components are usually accessible by casting the JAX-WS or JAX-RS artifacts into the underlying Apache CXF objects.
  2. Create an instance of the interceptor.
  3. Use the proper get method to retrieve the desired interceptor chain.
  4. Use the List object's add() method to attach the interceptor to the interceptor chain.
    Tip
    This step is usually combined with retrieving the interceptor chain.

Attaching an interceptor to a consumer

Example 57.4, “Attaching an interceptor to a consumer programmatically” shows code for attaching an interceptor to the inbound interceptor chain of a JAX-WS consumer.

Example 57.4. Attaching an interceptor to a consumer programmatically

package com.fusesource.demo; 

import java.io.File; 
import java.net.URL; 
import javax.xml.namespace.QName; 
import javax.xml.ws.Service; 

import org.apache.cxf.endpoint.Client;

public class Client 
{ 
  public static void main(String args[]) 
  { 
    QName serviceName = new QName("http://demo.eric.org", "stockQuoteReporter"); 
    Service s = Service.create(serviceName); 1

    QName portName = new QName("http://demo.eric.org", "stockQuoteReporterPort"); 
    s.addPort(portName, "http://schemas.xmlsoap.org/soap/", "http://localhost:9000/EricStockQuote"); 2
 
    quoteReporter proxy = s.getPort(portName, quoteReporter.class); 3

    Client cxfClient = (Client) proxy; 4

    ValidateInterceptor validInterceptor = new ValidateInterceptor(); 5
    cxfClient.getInInterceptor().add(validInterceptor); 6

    ...
  } 
}
1
Creates a JAX-WS Service object for the consumer.
2
Adds a port to the Service object that provides the consumer's target address.
3
Creates the proxy used to invoke methods on the service provider.
4
Casts the proxy to the org.apache.cxf.endpoint.Client type.
5
Creates an instance of the interceptor.
6
Attaches the interceptor to the inbound interceptor chain.

Attaching an interceptor to a service provider

Example 57.5, “Attaching an interceptor to a service provider programmatically” shows code for attaching an interceptor to a service provider's outbound interceptor chain.

Example 57.5. Attaching an interceptor to a service provider programmatically

package com.fusesource.demo; 
import java.util.*;

import org.apache.cxf.endpoint.Server;
import org.apache.cxf.frontend.ServerFactoryBean; 
import org.apache.cxf.frontend.EndpointImpl;

public class stockQuoteReporter implements quoteReporter 
{ 
  ... 
  public stockQuoteReporter()
  {
    ServerFactoryBean sfb = new ServerFactoryBean(); 1
    Server server = sfb.create(); 2
    EndpointImpl endpt = server.getEndpoint(); 3

    AuthTokenInterceptor authInterceptor = new AuthTokenInterceptor(); 4

    endpt.getOutInterceptor().add(authInterceptor); 5
  }
}
1
Creates a ServerFactoryBean object that will provide access to the underlying Apache CXF objects.
2
Gets the Server object that Apache CXF uses to represent the endpoint.
3
Gets the Apache CXF EndpointImpl object for the service provider.
4
Creates an instance of the interceptor.
5
Attaches the interceptor to the endpoint;s outbound interceptor chain.

Attaching an interceptor to a bus

Example 57.6, “Attaching an interceptor to a bus” shows code for attaching an interceptor to a bus' inbound interceptor chain.

Example 57.6. Attaching an interceptor to a bus

import org.apache.cxf.BusFactory;
org.apache.cxf.Bus;

...

Bus bus = BusFactory.getDefaultBus(); 1

WatchInterceptor watchInterceptor = new WatchInterceptor(); 2

bus..getInInterceptor().add(watchInterceptor); 3

...
1
Gets the default bus for the runtime instance.
2
Creates an instance of the interceptor.
3
Attaches the interceptor to the inbound interceptor chain.
The WatchInterceptor will be attached to the inbound interceptor chain of all endpoints created by the runtime instance.

57.3.3. Using Java annotations

Overview

Apache CXF provides four Java annotations that allow a developer to specify the interceptor chains used by an endpoint. Unlike the other means of attaching interceptors to endpoints, the annotations are attached to application-level artifacts. The artifact that is used determines the scope of the annotation's effect.

Where to place the annotations

The annotations can be placed on the following artifacts:
  • the service endpoint interface(SEI) defining the endpoint
    If the annotations are placed on an SEI, all of the service providers that implement the interface and all of the consumers that use the SEI to create proxies will be affected.
  • a service implementation class
    If the annotations are placed on an implementation class, all of the service providers using the implementation class will be affected.

The annotations

The annotations are all in the org.apache.cxf.interceptor package and are described in Table 57.2, “Interceptor chain annotations”.

Table 57.2. Interceptor chain annotations

AnnotationDescription
InInterceptors Specifies the interceptors for the inbound interceptor chain.
OutInterceptors Specifies the interceptors for the outbound interceptor chain.
InFaultInterceptors Specifies the interceptors for the inbound fault interceptor chain.
OutFaultInterceptors Specifies the interceptors for the outbound fault interceptor chain.

Listing the interceptors

The list of interceptors is specified as a list of fully qualified class names using the syntax shown in Example 57.7, “Syntax for listing interceptors in a chain annotation”.

Example 57.7. Syntax for listing interceptors in a chain annotation

interceptors={"interceptor1", "interceptor2", ..., "interceptorN"}

Example

Example 57.8, “Attaching interceptors to a service implementation” shows annotations that attach two interceptors to the inbound interceptor chain of endpoints that use the logic provided by SayHiImpl.

Example 57.8. Attaching interceptors to a service implementation

import org.apache.cxf.interceptor.InInterceptors;

@InInterceptors(interceptors={"com.sayhi.interceptors.FirstLast", "com.sayhi.interceptors.LogName"})
public class SayHiImpl implements SayHi
{
  ...
}