Reputation: 14419
I'm using Jersey to build a REST API to a service. I'd like to be able to accept and return both JSON and XML, and have this mostly working but I don't like the default "mapped" flavor of JSON that Jersey likes to spit out.
I know about the newer "natural" notation (from http://jersey.java.net/nonav/documentation/latest/json.html, which I'll quote at length because it makes obvious the problems with the default "mapped" notation):
After using mapped JSON notation for a while, it was apparent, that a need to configure all the various things manually could be a bit problematic. To avoid the manual work, a new, natural, JSON notation was introduced in Jersey version 1.0.2. With natural notation, Jersey will automatically figure out how individual items need to be processed, so that you do not need to do any kind of manual configuration. Java arrays and lists are mapped into JSON arrays, even for single-element cases. Java numbers and booleans are correctly mapped into JSON numbers and booleans, and you do not need to bother with XML attributes, as in JSON, they keep the original names
and would like to use it everywhere, but I haven't been able to figure out how to. I'm instantiating/configuring Jersey via Tomcat's XML config files -- using what I believe is the normal dance with servlet/servlet-class/init-param tags -- but I haven't been able to find documentation on whether or how it's possible to specify JSONConfiguration options from there.
I've also tried implementing my own ContextResolver which applies a JSONJAXBContext I instantiated from Java code, where I can apply JSONConfiguration.natural() (an example of this looks like this answer). This works, but only for types I explicitly list out in that code, and pass to the JSONJAXBContext constructor. Not only is this extra code to write and maintain, and change if I add more data classes, but it doesn't work for things like List.
Is there a way to tell Jersey to just use the natural notation instead of mapped notation, always and for all types?
Upvotes: 4
Views: 2976
Reputation: 14419
I never did find an answer to the actual question I was asking here, but instead I found a simple 3 step process that accomplishes the same end result that I wanted:
The Jersey documentation mentions this POJOMappingFeature/FEATURE_POJO_MAPPING prominently (it's the first example in the doc page I linked in the question), but doesn't describe exactly what it means, and from the way that document presents its information I thought this option (5.1, "POJO support") was at odds with option 5.2 ("JAXB based JSON support") which sounded more like what I wanted. So I tried a lot of other things before I tried enabling FEATURE_POJO_MAPPING.
But once I tried it, it worked exactly as I wanted, and I haven't had to look back.
A side benefit of this is that Jackson generates much better error messages in the case that the client passes it bogus JSON content, compared to Jersey's native JSON handling implementation.
Upvotes: 5