Friday, August 27, 2010

implementing fastinfoset using CXF

I recently experimented with FastInfoset (FI) and I got it working using CXF. FastInfoset is a standard that specifies a binary encoding format for XML Information set. It aims to provide more efficient serialization than text-base XML format.

One can think of FI as gzip for XML, though FI aims to optimize both document size and processing performance, whereas gzip optimizes only the size. While the original formatting is lost, no information is lost in the conversion from XML to FI and back to XML.

The java implementation of FI is available as part of GlassFish project. ( https://fi.dev.java.net/ ).


1) In your pom.xml make sure you get the cxf version 2.2.7 or later (Thanks to Daniel and Igor for fixing the bug promptly) and add FI dependency:

<dependency>
<groupId>sun-fi</groupId>
<artifactId>FastInfoset</artifactId>
<version>1.2.2</version>
</dependency>

....

<repository>
<id>fastinfoset</id>
<url>http://repository.jboss.org/maven2</url>
</repository>


2) in your service add this annotation.

@Produces({"application/xml","application/fastinfoset" })


3) in your configuration, add the interceptor, customTypes for the JAXBElementProvider and define it in your service:


<bean id="fastInfosetOutInterceptor" class="org.apache.cxf.interceptor.FIStaxOutInterceptor" />
<bean id="fastInfosetInInterceptor" class="org.apache.cxf.interceptor.FIStaxInInterceptor" />

<util:list id="customTypes">
<value>application/xml</value>
<value>application/fastinfoset</value>
</util:list>

<bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
<property name="produceMediaTypes" ref="customTypes" />
<property name="consumeMediaTypes" ref="customTypes" />
</bean>


<!-- JAX-RS endpoint configuration -->
<jaxrs:server id="sampleService" address="/">
<jaxrs:serviceBeans>
<ref bean="sampleServiceBean" />
</jaxrs:serviceBeans>
<jaxrs:providers>
<ref bean="jaxbProvider" />
</jaxrs:providers>
<jaxrs:outInterceptors>
<ref bean="fastInfosetOutInterceptor" />
</jaxrs:outInterceptors>
<jaxrs:inInterceptors>
<ref bean="fastInfosetInInterceptor" />
</jaxrs:inInterceptors>
</jaxrs:server>


4) When testing, make sure you add Accept header variable with value “Application/fastinfoset”, before hitting the endpoint. (Using the browser will not work).

TO TEST:
curl -H "Accept: Application/fastinfoset" http://localhost:8080/services/samples/getSample?id=9
SampleResponse{??version@1????Samples????ResponseMetadata???Service???Name?Foo????URL?http://foo????Hostname?

You can also add a FireFox Add-on called “Poster”