webjockey
webjockey

Reputation: 1755

JAXB JSON Jackson unmarshalling array/singleton list

JSON response

Case 1: only one element exists

{
"Person": {
    "first": "foo",
    "last": "bar"
}
}

Case 2: more than one element exists (ie) proper array type

{
"Person": [
    {
        "first": "foo",
        "last": "bar"
    },
    {
        "first": "cow",
        "last": "pal"
    }
]
}

JAXB code which generate above responses which i dont have a control over.

@XmlRootElement
public class PersonContainer {

@XmlElement
List<Person> personList;
}

I use Jackson parser's JAXB feature to unmarshal the JSON to JAXB object. Since there are two types of response is possible , the Jackson parser is not working correctly for Case 1 response.

How do i handle both cases correctly and bind the JSON response?

Upvotes: 1

Views: 4115

Answers (2)

Bala
Bala

Reputation: 11

I found a solution: replace the JAXB JSON serializer with a better behaved JSON serializer like Jackson. The easy way is to use jackson-jaxrs, which has already done it for you. The class is JacksonJsonProvider. All you have to do is edit your project's web.xml so that Jersey (or another JAX-RS implementation) scans for it. Here's what you need to add:

<init-param>
  <param-name>com.sun.jersey.config.property.packages</param-name>
  <param-value>your.project.packages;org.codehaus.jackson.jaxrs</param-value>
</init-param>

And that's all there is to it. Jackson will be used for JSON serialization, and it works the way you expect for lists and arrays.

It works for me, make sure jackson-jaxrs.jar in your class path.

Reference: How can I customize serialization of a list of JAXB objects to JSON?

Upvotes: 1

webjockey
webjockey

Reputation: 1755

It looks like some custom coding is necessary for the above cases

Map the list with the following

          @JsonDeserialize(using=PersonSerializer.class)
          List<Person> personList;

Implement PersonSearializer

         public class PersonSerializer extends JsonDeserializer<List<Person>>{

public List<Person> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
    throws IOException, JsonProcessingException {
     ObjectCodec oc = jsonParser.getCodec();
     JsonNode node = oc.readTree(jsonParser);
     Iterator<JsonNode>  iterator = node.getElements();

     List<Person> list = new ArrayList<Person>();
     while (iterator.hasNext()){
         JsonNode j = iterator.next();
         Person nr = new Person();
         if (j.get("first") == null) {
             nr.setFirstName(node.get("first").getTextValue()));
             nr.setLastName(node.get("last").getTextValue()));
             list.add(nr);
             break;
         }
         nr.setFirstName(j.get("first").getTextValue()));
         nr.setLastName(j.get("last").getTextValue()));
         list.add(nr);
     }

     return list;
}

}

Upvotes: 1

Related Questions