Sunday, 5 August 2012

JAXB JSON Marshalling / Unmarshalling

The Jackson library offers a library to process objects with JAXB annotations, but it Jackson does not support all JAXB annotations (see the bottom of this page for more information).

The code example uses the following Java class:
@XmlRootElement()
public class Recipe {

    private String title;
    private int duration;

    public String getTitle() {
        return title;
    }

    @XmlTransient
    public void setTitle(String title) {
        this.title = title;
    }

    public int getDuration() {
        return duration;
    }

    @XmlElement
    public void setDuration(int duration) {
        this.duration = duration;
    }

}
We deliberately annotate the title as transient to prove that Jackson processes JAXB annotations and does not rely on the standard Pojo to JSON processus.

The following code performs the marshalling / unmarshalling:
Recipe recipe = new Recipe();
recipe.setDuration(30);
recipe.setTitle("Chicken recipe");
        
ObjectMapper mapper = new ObjectMapper();
        
AnnotationIntrospector introspector
    = new JaxbAnnotationIntrospector();
mapper.setAnnotationIntrospector(introspector);
        
// Printing JSON
String result = mapper.writeValueAsString(recipe);
System.out.println(result);
        
// Parsing JSON
Recipe retr = mapper.readValue(result, Recipe.class);
        
System.out.println("Title   : " + retr.getTitle());
System.out.println("Duration: " + retr.getDuration());
It relies on the following dependency:
<dependency>
  <groupId>com.fasterxml.jackson.module</groupId>
  <artifactId>jackson-module-jaxb-annotations</artifactId>
  <version>2.0.5</version>
</dependency>
And produces the following:
{"duration":30}
Title   : null
Duration: 30

Pojo to XMLPojo to JSONJAXB to XMLJAXB to JSON • JAXB Annotations Tutorial Table Of Content

2 comments:

  1. Hello Jérôme,

    I'm the EclipseLink JAXB (MOXy) lead and you may be interested in our JSON-binding. We support all of the JAXB (JSR-222) annotations and constructs such as JAXBElement:
    - JSON Binding with EclipseLink MOXy - Twitter Example

    -Blaise

    ReplyDelete
  2. Hello.
    I am using JBoss RESTeasy with resteasy jettison provider. But I cannot deserialize the produced JSON string like it is done in you example.
    The difference is I use @XmlRootElement(name="...").
    Here it is:
    @XmlRootElement(name = "customer")
    public class Customer implements Entity {
    ...
    }

    The generated JSON is:
    "{"customer":{"email":[{"address":"alan@gmail.com","id":1},{"default":true,"address":"alan@hotmail.com","id":2}],"id":1,"name":"Allan","surname":"Powder"}}"

    The code for deserialing is:
    public static T fromJSONString(final Class clazz, final String input)
    throws IOException {

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector());

    T result = objectMapper.readValue(input, clazz);

    return result;
    }

    But I have en exception:
    com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "customer" (class com.noveo.training.jsbackend.model.impl.Customer), not marked as ignorable (7 known properties: , "address", "name", "id", "birthdayDate", "surname", "email", "phone"])

    I suppose, it is expected the customer object but instead of that the value is unknown object which contains customer.
    Here is my RESTEasy service annotation:
    @Path("/customer")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public interface CustomerService {
    ...
    @POST
    @Path("/get")
    public Customer getCustomer(@QueryParam("customerId") final Integer id);
    ...
    }

    Could you please explain what is wrong in my case?

    ReplyDelete