Skip to content
Andrew Byrd edited this page Feb 17, 2014 · 9 revisions

Definitions

This Stack Overflow response clarifies the relationship: http://stackoverflow.com/a/17981041/778449 The JAX-RS implementation needs to receive and send objects (request and response bodies) over HTTP. When JAX-RS wants to return a response with the application/xml media type, it uses JAXB to figure out how to write objects out as XML.

JAXB entails adding annotations to classes indicating what fields should be serialized and how. Those annotations (which include the letters XML) can be applied equally well to XML or JSON serialization, but there are ugly points (content vs. attributes distiction in XML).

It appears that Jersey does not automatically include a JSON MessageWriter, because if you remove the Maven dependency com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider from the POM, then requests for Content-type:appication/json will fail with a:

javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class org.opentripplanner.api.model.transit.RouteList, and Java type class org.opentripplanner.api.model.transit.RouteList, and MIME media type application/json was not found

You need a JSON library that implements the extension points MessageBodyReader/Writer of JAX-RS, then declares its implementations to Java's "service loader mechanism", allowing Jersey (and other software) to automatically detect and use it for JSON parsing/writing.

Some wisdom gleaned from Stack Overflow and wikis on choosing and using a JSON library: -"Jackson and Gson are the most complete Java JSON packages regarding actual data binding support; many other packages only provide primitive Map/List (or equivalent tree model) binding." So Jackson and Gson allow marshalling and unmarshalling objects, other libraries may just parse the JSON into a tree of strings. -Jackson 1.x and 2.x live in different Java packages (1.x under org.codehaus.jackson, 2.x under com.fasterxml.jackson), be sure to import Jackson objects from matching versions. -Do not use Maven dependencies jersey-media-json (doesn't exist anymore in Jersey 2.x) and jersey-json (only for Jersey 1.x). Use either jersey-media-moxy (for JAXB) or jersey-media-json-jackson (for POJO). The Jersey User Guide has information on these modules in the JSON section at https://jersey.java.net/documentation/latest/media.html#json (note that we are using yet another module from Jackson itself, I have no idea what the difference is). -"As of v1.18 of Jersey you do NOT need to write your own MessageBodyWriter and the return type of your @GET methods can be POJO-objects." -"Jackson 1.7 added ability to register serializers and deserializes via Module interface. This is the recommended way to add custom serializers -- all serializers are considered "generic", in that they are used for subtypes unless more specific binding is found. The simplest way is to extend SimpleModule, add serializer(s), and register module with ObjectMapper."

POJO Mapping

We are using "POJO mapping" and "natural" serialization rather than JAXB. POJO mapping means just converting the public fields and getters of objects to JSON naturally, rather than requiring annotations.

We do need to somehow enable the "POJO mapping feature", which maps public fields and getters of objects to XML/JSON instead of requiring annotations, and "natural mapping" lest we automatically get "Badgerfish" JSON style which perfectly reproduces the semantics of XML but is bizarrely non-idiomatic in JSON.

Natural vs. Badgerfish Serialization

Doc Links

The documentation on this wiki is outdated and should not be used

unless you are intentionally working with legacy versions of OpenTripPlanner. Please consult the current documentation at readthedocs

Clone this wiki locally