Saturday, January 26, 2013

Marshaling POJOs with Jersey

When a web service has multiple consumers, you obviously don't want to duplicate a lot of code.  So what if you want to push data to/from a Java API and a web site like jQuery?  Jersey can help you do both with JSON.  A lot of what I'll cover is in the Jersey docs.
  • Turn JSON support on in your servlet's web.xml:
<init-param>
  <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
  <param-value>true</param-value>
</init-param>
  • This example also uses compression so add the gzip filters too.
  • Annotate your POJO with JAXB.  Make sure you have an empty constructor.  I like to make the member variables private and force use of public getters.  I also elect to ignore unknown properties.
@XmlRootElement(name = "foo")
@XmlAccessorType(XmlAccessType.PUBLIC_METHOD)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Foo {
    private String blah;

    Foo() {}
    
    @XmlElement()
    public String getBlah() { return blah; }
}
  • Set up your web service.  Since you're returning JSON, jQuery will be happy with basically no further consideration.  Note I didn't define a setBlah() above but I hope you get the picture.  
@GET @Path("/")
@Produces({MediaType.APPLICATION_JSON})
public Foo getFoo() {
  Foo foo = new Foo();
  foo.setBlah("Hello!");
  return foo;
}
  • Connect your WebResource properly.  Note the addition of the JacksonJsonProvider class.  The gzip filter is not required but you should probably use it.

ClientConfig config = new DefaultClientConfig();
config.getClasses().add(JacksonJsonProvider.class);
Client client = Client.create(config);
client.addFilter(new GZIPContentEncodingFilter(true)); 
WebResource webResource = client.resource(hostname);
  • Now request your POJO response (note the use of gzip here):

Foo foo = webResource.path("/")
               .header("Accept-Encoding", "gzip")
               .get(new GenericType<Foo>() {});
  • You can also pass POJOs to the web service using POSTs.  This snippet assumes you annotated class Bar is a similar manner to Foo and the "/bar" POST endpoint accepts a Bar object.

Bar bar = new Bar("stuff");

Foo foo = webResource.path("/bar").post(new GenericType<Foo>() {}, bar);

Edited on 2/10/13 to include compression in example.

No comments:

Post a Comment