whaley

Drawing a Blank

Multiple Content Types in JAX-RS

A client of mine, who has primarily written all of their service with a combination of SOAP/JAX-WS and usage of , has expressed an interest in moving to a REST based architecture instead for integrating the many components in their system. I’ve spent most of my SOA life working with legacy integrations and using SOAP, and while I’ve paid attention to REST and understand what the heck it is about, I’ve done very little in the way of actually writing REST services in Java and only dabbling a small bit in Python.

In my client’s current project, we already have a metric ton of classes that are JAXB annotated, so exposing those through JAX-RS is quite a cinch. However, another curiousity we had was how easily could reuse the same classes for both an xml payload format and another payload format (json, for example). I know this is actually a common idiom in some REST services (twitter, for example), though to be honest I’d recommend only using one format. Regardless being able to support both in some kind of fashion during migration is definitely a valid case.

So I whipped up the world’s simplest little proof of concept showing how you can actually do this with JAX-WS. I’m leaving out lots of details, and am only supporting GET operations here, but this at least demonstrates how one can support multiple formats.

First our JAXB annotated model class that we want to expose:

And our actual service class:

Notice how I have the @Path defined on a per method basis. Basically, this allows me to setup a path ending in .json that has a @Produces of only “application/json”, and a similar method for Xml only. I also include an additional method that doesn’t specify an extension on the end of the path and has a @Produces annotation allowing for both “application/json” and “application/xml”.

The result? Well, I can first use the Accept header in my http request to signal which format my client wants. In all honesty, this is probably the more pure HTTP way to select which format you want to use

However, since I’m using @Path annotations on specific methods, I can request the resources I want with the payload format I want by also specifying the extension on the end of the path.

I’m using as my JAX-RS implementation of choice:

The cxf-bundle-jaxrs dependency brings along for json parsing and for XML parsing, so both formats are able to be handled.

Comments