I am successfully marshaling a POJO into JSON using JAX-RS and JAXB annotations.
The problem is that when I am trying to use the same for un-marshalling my request it doesn’t work. As far as I can see in the documentation JAX-RS can automatically marshal and unmarshal application/json strings back to java classes.
Do I need to create my own MessageBodyReader for that, or this is supported by the framework without using Jackson libraries?
Marshalling to XML is easy, but it took me a while to figure out how to marshall to JSON. Pretty simple after you find the solution though.
public static String marshalToXml( Object o ) throws JAXBException {
StringWriter writer = new StringWriter();
Marshaller marshaller = JAXBContext.newInstance( o.getClass() ).createMarshaller();
marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true );
marshaller.marshal( o, writer );
return writer.toString();
}
public static String marshalToJson( Object o ) throws JAXBException {
StringWriter writer = new StringWriter();
JAXBContext context = JSONJAXBContext.newInstance( o.getClass() );
Marshaller m = context.createMarshaller();
JSONMarshaller marshaller = JSONJAXBContext.getJSONMarshaller( m );
marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, true );
marshaller.marshallToJSON( o, writer );
return writer.toString();
}
I have been doing it successfully in RESTEasy. I have it set up to consume and produce both XML and JSON. Here is a request handler:
@POST
@Produces(["application/json","application/xml"])
@Consumes(["application/json","application/xml"])
@Path("/create")
public Response postCreate(
ReqData reqData) {
log.debug("data.name is "+ data.getName());
...
return Response.status(Response.Status.CREATED)
.entity(whatever)
.location(whateverURI)
.build();
}
ReqData is a JavaBean, i.e. it has a default constructor and it has setters and getters that the marshaller finds. I don't have any special JSON tags in ReqData, but I do have @XmlRootElement(name="data") at the top for the XML marshaller and @XmlElement tags on the setters.
I use separate beans for input and output, but as far as I know you can use the same bean.
The client program sends the JSON string in the entity-body of the request, and sets the Context-Type and Accept headers both to "application/json".
I've been working with Apache Wink and for that I have needed to use a JSON provider, such as Jettison (a colleague has been using Jackson). I wrote up the steps I took here
My guess is that you too will need to to use a JSON provider. Is there a reason not to use a Jackson provider?