-
Notifications
You must be signed in to change notification settings - Fork 1k
APISerialization
- JAX-RS is the "Java API for RESTful Web Services". It defined @Path, @GET, @PUT, @Produces, @PathParam, @QueryParam etc. We use the JAX-RS reference implementation called Jersey. see http://en.wikipedia.org/wiki/Java_API_for_RESTful_Web_Services
- JAXB is the "Java Architecture for XML Binding", which maps Java classes to XML representations so they can be marshalled and unmarshalled. see http://en.wikipedia.org/wiki/JAXB
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."
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.
unless you are intentionally working with legacy versions of OpenTripPlanner. Please consult the current documentation at readthedocs