/var/log/balo

Permission denied to call method PandorasBox.open

Proper JSON output with JAX-RS

10 Mar 2013

I had to develop a REST webservice endpoint recently in our JavaEE application. After we figured out what data the client needs we came to an agreement that we will produce JSON output. I knew JAX-RS can do that, so I simply wrote a method like this:

@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/get/{param1}/{param2}")
public List<ApprovedEntrant> getEntrants(
            @PathParam("param1") final String param1,
            @PathParam("param2") final String param2) {

     final List<ApprovedEntrant> entrants = new LinkedList<ApprovedEntrant>();

     // put elements in the list

     return entrants;
}

It seems to work as expected but sometimes we noticed weird results with the default JSON serialization of JAX-RS in Glassfish 3 (maybe Jersey?):

  • in case of an empty list (!), it produces "null" string output
  • if the list contains only one element, the result is the element in JSON object, instead of a JSON array with one element

Of course, I could import the official JSON Java library and do some toString() or object transform tricks, but I don’t want to introduce another dependency in my widely used domain project. I want to solve it in the webservice layer, without manual object / list JSON transformations. After some research I found the Jackson project which has a smarter JAX-RS JSON provider.

First, I added the new dependency to my webservice project:

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.1.4</version>
</dependency>

Then I had to modify my code a bit, but I think quite general and doesn’t contain ugly JSON objects and arrays.

private static ObjectMapper mapper = new ObjectMapper();

@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/get/{param1}/{param2}")
public String getEntrants(
            @PathParam("param1") final String param1,
            @PathParam("param2") final String param2) {

     final List<ApprovedEntrant> entrants = new LinkedList<ApprovedEntrant>();

     // put elements in the list

     String out = "";
     try {
         out = mapper.writeValueAsString(entrants);
     } catch (JsonProcessingException ex) {
         //error handling
     }

     return out;
}
Facebook Twitter Google+
Tags: coding, english, java, jax-rs, json, rest, and webservice
comments powered by Disqus