5

I have a JSON structure that looks like this:

{"data": [{"mykey": "someval"}, {"mykey": "someotherval"}], "foo": "bar"}

I also have

public MyClass {
    public String mykey;
}

Now I would like to deserialize the content of "data" of my JSON into a List<MyClass> using Jackson, so I have this code:

ObjectMapper mapper = new ObjectMapper();
List<MyClass> l = (List<MyClass>) mapper.readerFor(new TypeReference<List<MyClass>>(){}).
    withRootName("data").readValue(myJSONString);

However this gives me an exception:

com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (FIELD_NAME), 
expected END_OBJECT: Current token not END_OBJECT (to match wrapper object with root name 
'data'), but FIELD_NAME

Anyone know what I need to do to get this parsed?

1 Answers1

4

Update

List<MyClass> l = (List<MyClass>) mapper.readValue(mapper.readTree(myJSONString).findPath("data").toString(),
                                  new TypeReference<List<MyClass>>(){});

This one line will retrieve the list you are looking for. The problem with what you are trying to do is you are trying to deserialize for the case where the data constitutes the JSON like

{"data":[{"mykey": "someval"}, {"mykey": "someotherval"}]}

But your JSON has additional values which is causing the issue. The above code isolates the data array using the Jackson JSON tree parser and then deserailize it in to the list.

Initial answer

Have a root object so that you can capture the list within that object.

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"data"
})
public class Root {

@JsonProperty("data")
private List<MyClass> data = null;

@JsonProperty("data")
public List<MyClass> getData() {
return data;
}

@JsonProperty("data")
public void setData(List<MyClass> data) {
this.data = data;
}
}

Now use the objectMapper to deserialize to this object.

Root root = mapper.readValue(myJSONString,Root.class);

Let me know how it works out.

Coder
  • 2,153
  • 1
  • 16
  • 21
  • Yes, a root object worked. Thanks for the suggestion. I did not have to put any of the @JsonProperty/@JsonInclude/@JsonPropertyOrder annotations in to make it work, but I did have to add @JsonIgnoreProperties("foo") to get it to parse without complaining about this property that I don't need to read. I would still be interested if this can be done without root class though, since it does not have any logical value to me... – David Bosschaert Mar 06 '17 at 17:54
  • I am afraid you have to write a custom deserializer in that case. Are you ok with such implementation? – Coder Mar 06 '17 at 19:05