Proper JSON output with JAX-RS
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:
1@GET
2@Produces(MediaType.APPLICATION_JSON)
3@Path("/get/{param1}/{param2}")
4public List<ApprovedEntrant> getEntrants(
5 @PathParam("param1") final String param1,
6 @PathParam("param2") final String param2) {
7
8 final List<ApprovedEntrant> entrants = new LinkedList<ApprovedEntrant>();
9
10 // put elements in the list
11
12 return entrants;
13}
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:
1<dependency>
2 <groupId>com.fasterxml.jackson.jaxrs</groupId>
3 <artifactId>jackson-jaxrs-json-provider</artifactId>
4 <version>2.1.4</version>
5</dependency>
Then I had to modify my code a bit, but I think it’s quite normal and doesn’t contain ugly JSON objects and arrays.
1private static ObjectMapper mapper = new ObjectMapper();
2
3@GET
4@Produces(MediaType.APPLICATION_JSON)
5@Path("/get/{param1}/{param2}")
6public String getEntrants(
7 @PathParam("param1") final String param1,
8 @PathParam("param2") final String param2) {
9
10 final List<ApprovedEntrant> entrants = new LinkedList<ApprovedEntrant>();
11
12 // put elements in the list
13
14 String out = "";
15 try {
16 out = mapper.writeValueAsString(entrants);
17 } catch (JsonProcessingException ex) {
18 //error handling
19 }
20
21 return out;
22}