Friday, November 30, 2012

CXF XSLT Feature

XSLT Feature

 CXF XSLT Feature is introduced as alternative of lightweight CXF Transformation Feature.
The most transformation use cases can be implemented using Transformation Feature: dropping the namespace of the outbound messages; qualifying the incoming message; changing namespaces; appending or dropping elements; converting attributes to elements.

But it can be not enough for some advanced transformations. If you have to implement non-trivial transformation, not supported by Transformation Feature - it is use case for XSLT Feature. Here the full power of XSL is available.
Therefore decision which feature should be used is very easy: CXF Transformation Feature for simple transformations and CXF XSLT Feature for advanced transformations, not supported by lightweight variant.

Configuration

Spring configuration of XSLT Feature is very easy, it is necessary just to configure XSL script for inbound and/or outbound transformation:
<bean id="xsltFeature" class="org.apache.cxf.feature.transform.XSLTFeature">          
      <property name="inXSLTPath" value="requestTransformation.xsl" />          
      <property name="outXSLTPath" value="responseTransformation.xsl" />  
</bean>

After it, feature can be added to client or endpoint:
<jaxws:client id="customerService" serviceName="customer:CustomerServiceService"
  endpointName="customer:CustomerServiceEndpoint" address="http://localhost:9091/CustomerServicePort"
  serviceClass="com.example.customerservice.CustomerService">
  <jaxws:features>
     <ref bean="xsltFeature" />
  </jaxws:features>
</jaxws:client>

<jaxws:endpoint xmlns:customer="http://customerservice.example.com/"
  id="CustomerServiceHTTP" address="http://localhost:9090/CustomerServicePort"
  serviceName="customer:CustomerServiceService" endpointName="customer:CustomerServiceEndpoint"
  implementor="com.example.customerservice.server.CustomerServiceImpl">
  <jaxws:features>
     <ref bean="xsltFeature" />
  </jaxws:features>
</jaxws:endpoint>

It is also possible to add XSLT interceptors directly in Java code:
 CustomerServiceService service = new CustomerServiceService();
 CustomerService customerService = service.getCustomerServicePort();
 Client client = ClientProxy.getClient(customerService);
 XSLTOutInterceptor outInterceptor = new XSLTOutInterceptor(Phase.PRE_STREAM, StaxOutInterceptor.class, null,
                                                            XSLT_REQUEST_PATH);
 client.getOutInterceptors().add(outInterceptor);

By default XSLT interceptors run on POST_STREAM and PRE_STREAM phases.
In some cases it may be needed to change the phase, for example, the in transformation has to be applied after the encrypted payload has been decrypted and its signature checked.
For such transformations to succeed XLSTInInterceptor/XSLTOutInterceptor will need to be created with a constructor accepting a 'phase' String parameter.

The XSLT interceptors support following message contents:
  • InputStream/OutputStream;
  • Reader/Writer;
  • XMLStreamReader/XMLStreamWriter.
Therefore the interceptors can be used on different phases and can also work with JMS Transport using JMS Text messages (produces Reader/Writer message contents).
 

2 comments:

  1. Very helpful post..I am trying to group some element during unmarshalling using XSL transaformation technique..Is it some supported for JAXRS as well?

    Also can i use , transformation feature for marshaling and xsl feature for un marshaling?

    ReplyDelete
  2. Hi,

    > Is it some supported for JAXRS as well?
    Yes, you can use for JAXWS as well for JAXRS CXF implementations

    > Also can i use , transformation feature for marshaling and xsl feature for un marshaling
    Sure you can do it. Even nothing prevent to apply both features for marshaling or un-marshaling only.

    ReplyDelete