CXF Customizations - 6.3

Talend ESB Service Developer Guide

EnrichVersion
6.3
EnrichProdName
Talend Data Fabric
Talend Data Services Platform
Talend ESB
Talend MDM Platform
Talend Open Studio for ESB
Talend Real-Time Big Data Platform
task
Design and Development
Installation and Upgrade
EnrichPlatform
Talend ESB

Annotations

CXF provides several custom annotations that can be used to configure and customize the CXF runtime.

org.apache.cxf.feature.Features

The @Features annotation is used to add Features, something that is able to customize a Server, Client, or Bus, typically by adding capabilities. See the CXF Features List for those provided "out of the box" by CXF. You can also create your own features. In many cases, however, those features have Annotations themselves which can be used and provide greater control over configuration.

org.apache.cxf.interceptor.InInterceptors, org.apache.cxf.interceptor.OutInterceptors, org.apache.cxf.interceptor.OutFaultInterceptors, org.apache.cxf.interceptor.InFaultInterceptors

Add interceptors to the various chains used to process messages.

org.apache.cxf.annotations.WSDLDocumentation org.apache.cxf.annotations.WSDLDocumentationCollection (since 2.3)

For "java first" scenarios where the WSDL is derived from the Java interfaces/code, these annotations allow adding wsd:documentation elements to various locations in the generated wsdl.

For example:

@WebService
@WSDLDocumentationCollection(
   {
      @WSDLDocumentation("My portType documentation"),
      @WSDLDocumentation(value = "My top level documentation",
         placement = WSDLDocumentation.Placement.TOP),
      @WSDLDocumentation(value = "My binding doc",
         placement = WSDLDocumentation.Placement.BINDING)
   }
)
public interface MyService {

   @WSDLDocumentation("The docs for echoString")
   String echoString(String s);

}

org.apache.cxf.annotations.SchemaValidation (since 2.3)

Turns on SchemaValidation for messages. By default, for performance reasons, CXF does not validate message against the schema. By turning on validation, problems with messages not matching the schema are easier to determine.

org.apache.cxf.annotations.DataBinding (since 2.2.4)

Sets the DataBinding class that is associated with the service. By default, CXF assumes you are using the JAXB data binding. However, CXF supports different databindings such as XMLBeans, Aegis, SDO, and possibly more. This annotation can be used in place of configuration to select the databinding class.

@DataBinding(org.apache.cxf.sdo.SDODataBinding.class)
public interface MyService {
   public commonj.sdo.DataObject echoStruct(
      commonj.sdo.DataObject struct
   );
}

org.apache.cxf.annotations.Logging (since 2.3)

Turns on logging for the endpoint. Can be used to control the size limits of what gets logged as well as the location. It supports the following attributes:

limit

Sets the size limit after which the message is truncated in the logs. Default is 64K

inLocation

Sets the location to log incoming messages. Can be <stderr>, <stdout>, <logger>, or a file: URL. Default is <logger>

outLocation

Sets the location to log outgoing messages. Can be <stderr>, <stdout>, <logger>, or a file: URL. Default is <logger>

@Logging(limit=16000, inLocation="<stdout>")
public interface MyService {

   String echoString(String s);

}

org.apache.cxf.annotations.GZIP (since 2.3)

Enables GZIP compression of on-the-wire data. Supported attributes:

threshold

the threshold under which messages are not gzipped

GZIP is a negotiated enhancement. An initial request from a client will not be gzipped, but an Accept header will be added and if the server supports it, the response will be gzipped and any subsequent requests will be.

org.apache.cxf.annotations.FastInfoset (since 2.3)

Enables FastInfoset of on-the-wire data. Supported attributes:

force

forces the use of fastinfoset instead of negotiating. Default is false

FastInfoset is a negotiated enhancement. An initial request from a client will not be in fastinfoset, but an Accept header will be added and if the server supports it, the response will be in fastinfoset and any subsequent requests will be.

org.apache.cxf.annotations.EndpointProperty org.apache.cxf.annotations.EndpointProperties (since 2.3)

Adds a property to an endpoint. Many things such as WS-Security related things and such can be configured via endpoint properties. Traditionally, these would be set via the <jaxws:properties> element on the <jaxws:endpoint> element in the spring config, but these annotations allow these properties to be configured into the code.

@WebService
@EndpointProperties(
   {
      @EndpointProperty(key = "my.property", value="some value"),
      @EndpointProperty(key = "my.other.property", 
         value="some other value"),
   })
public interface MyService {
   String echoString(String s);
}

org.apache.cxf.annotations.Policy org.apache.cxf.annotations.Policies (since 2.3)

Used to attach WS-Policy fragments to a service or operation. The Policy supports the attributes:

uri

REQUIRED the location of the file containing the Policy definition

includeInWSDL

Whether to include the policy in the generated WSDL when generating a wsdl. Default it true

placement

Specify where to place the policy

faultClass

if placement is a FAULT, this specifies which fault the policy would apply to

Note

When using a custom Spring configuration, you'll need to import META-INF/cxf/cxf-extension-policy.xml

@Policies({
   @Policy(uri = "annotationpols/TestInterfacePolicy.xml"),
   @Policy(uri = "annotationpols/TestImplPolicy.xml",
      placement = Policy.Placement.SERVICE_PORT),
   @Policy(uri = "annotationpols/TestPortTypePolicy.xml", 
      placement = Policy.Placement.PORT_TYPE)
})
@WebService
public static interface TestInterface {
   @Policies({
       @Policy(uri = "annotationpols/TestOperationPolicy.xml"),
       @Policy(uri = "annotationpols/TestOperationInputPolicy.xml", 
          placement = Policy.Placement.BINDING_OPERATION_INPUT),
       @Policy(uri = "annotationpols/TestOperationOutputPolicy.xml", 
          placement = Policy.Placement.BINDING_OPERATION_OUTPUT),
       @Policy(uri = "annotationpols/TestOperationPTPolicy.xml", 
          placement = Policy.Placement.PORT_TYPE_OPERATION),
       @Policy(uri = "annotationpols/TestOperationPTInputPolicy.xml", 
          placement = Policy.Placement.PORT_TYPE_OPERATION_INPUT),
       @Policy(uri = "annotationpols/TestOperationPTOutputPolicy.xml", 
          placement = Policy.Placement.PORT_TYPE_OPERATION_OUTPUT)
   })
   int echoInt(int i);
}

org.apache.cxf.annotations.UseAsyncMethod (since 2.6.0)

Used on the JAX-WS service implementation object to mark a method as preferring the 'async' version of the method instead of the synchronous version. With JAX-WS, services default to the synchronous methods that require the returning value to be returned from the method. By marking a method with the @UseAsyncMethod annotation, if the transport supports it, CXF will call the async version that takes an AsynHandler object and the service can call that handler when the response is ready. If the transport does not support the CXF continuations, the synchronous method will be called as normal.

Dynamic Clients

The usual way to construct a web service client is to include the Java interface for the service (the SEI) and any classes that are used for inputs and output in the client application. This is not always desirable or practical.

CXF supports several alternatives to allow an application to communicate with a service without the SEI and data classes. JAX-WS specified the Dispatch API, as well as the Provider interface for reading and writing XML. This page, however, describes the dynamic client facility of CXF. With dynamic clients, CXF generates SEI and bean classes at runtime, and allows you to invoke operations via APIs that take Objects, or by using reflection to call into full proxies.

Note that, in general, CXF only supports WSI-BP services. If you attempt to create a dynamic client for a WSDL that uses features outside of WSI-BP, CXF may throw an exception.

DynamicClientFactory and JaxWsDynamicClientFactory

CXF provides two factory classes for dynamic classes. If your service is defined in terms of JAX-WS concepts, you should use the JaxWsDynamicClientFactory. If you do not want or need JAX-WS semantics, use the DynamicClientFactory. The remainder of this page uses the JaxWs version.

Let's pretend for a moment that you have a WSDL which defines a single operation "echo" which takes an input of a string and outputs a String. You could use the JaxWsDynamicClientFactory for it like this:

JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("echo.wsdl");

Object[] res = client.invoke("echo", "test echo");
System.out.println("Echo response: " + res[0]);

Many WSDLs will have more complex types though. In this case the JaxWsDynamicClientFactory takes care of generating Java classes for these types. For example, we may have a People service which keeps track of people in an organization. In the sample below we create a Person object that was generated for us dynamically and send it to the server using the addPerson operation:

JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("people.wsdl", classLoader);

Object person = Thread.currentThread().getContextClassLoader().
   loadClass("com.acme.Person").newInstance();

Method m = person.getClass().getMethod("setName", String.class);
m.invoke(person, "Joe Schmoe");

client.invoke("addPerson", person);

You may be asking yourself the following question: "Where did the class name 'com.acme.Person' come from?"

One way to get the class names is to run wsdl2java and examine the results. The dynamic client factory uses the same code generator as that tool. Another way is to walk the CXF service model. This has the advantage that it delivers Class<?> objects directly, so you don't need to obtain the correct class loader reference and run loadClass.

The wsdl_first_dynamic_client sample uses this approach. Read the file 'ComplexClient.java' to see the process, which uses some of the java.bean classes to simplify the code slightly.

Note

The JaxWsDynamicClientFactory sets the Thread context ClassLoader to a new ClassLoader that contains the classes for the generated types. If you need the original ClassLoader, make sure you save it prior to calling createClient.