7
votes

I'm using JAX-RS to create restful webservices in Java. I am getting to much overhead in the produced JSON.

Data class:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Test {

    private Map<String,String> data;

    Test() {}

    public Test(Map<String,String> data) {
        this.data = data;
    }

    public Map<String, String> getData() {
        return data;
    }
}

Service:

@GET
@Path("/test")
@Produces("application/json; charset=UTF-8;")
public Test test() {
   Map<String,String> map = new HashMap<String,String>();
   map.put("foo", "bar");
   map.put("bingo", "bongo");
   return new Test(map);
}

Produces:

{"data":{"entry":[{"key":"foo","value":"bar"},{"key":"bingo","value":"bongo"}]}}

I would like it to produce:

{"data":{"foo":"bar","bingo":"bongo"}}

What is the simplest way to achive this? I am free to redifine my data class but I can't know in advance the keys or size of the map.

3
Given the overhead of the web request, are you sure the json format is worth optimizing? (In other words, did profiling your application lead you to believe the format of the json data was a performance issue?) Remember... Premature optimization is the root of all evil in programmingRob Andrews

3 Answers

5
votes

Simplest way would be using List<Pair> instead where Pair is just a Javabean with two properties.

1
votes
1
votes

If you don't use JAXB annotated objects, but simple POJO's, you can get the correct behaviour by simply enabling the POJO mapping feature, together with the Jackson JSON library.

So in web.xml, if you're using the filter (similar for servlet), your configuration should be:

<filter>
  <filter-name>Jersey</filter-name>
  <filter-class>...</filter-class>
  <init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
  </init-param>
</filter>

And just depend on the jersey-json dependency in your maven config, or download it from the website and put jackson in your classpath. See also this answer and this answer, and this blog post. And why on earth this is not standard behaviour I do not know.