Parsing an array of non-homogeneous JSON Objects with Jackson

Karlson :

I have a situation where I need to parse an array of JSON objects that are not identical.

So for example:

[ 
 { "type": "type1", ..... type1 contents .... }, 
 { "type": "type2", ..... type2 contents .... },
 ....
 { "type": "type1", ..... type1 contents .... }
]

The number of types is limited and the contents of each type are well can be defined but it is not possible to define a single type of object that will hold the contents.

Is there a way to parse them with Jackson?

P.S. I am trying to avoid writing a custom parser if I can help it.

Nonika :

I would use

com.fasterxml.jackson.databind.JsonNode.

JsonNode parsed = objectMapper
                   .readValue("[{\"name\": \"a\"},{\"type\":\"b\"}]", JsonNode.class);

This class has tons of utility methods to work with.

Or specific for arrays you can use:

com.fasterxml.jackson.databind.node.ArrayNode

ArrayNode value = objectMapper
                   .readValue("[{\"name\": \"a\"},{\"type\":\"b\"}]", ArrayNode.class);

EDIT

Sorry, I have misread your question, you can use @JsonTypeInfo for polymorphic serialization/deserialization:

public static void main(String args[]) throws JsonProcessingException {

    //language=JSON
    String data = "[{\"type\":\"type1\", \"type1Specific\":\"this is type1\"},{\"type\":\"type2\", \"type2Specific\":\"this is type2\"}]";
    ObjectMapper objectMapper = new ObjectMapper();

    List<BaseType> parsed = objectMapper.readValue(data, new TypeReference<List<BaseType>>() {});
    System.out.println(parsed);
}


@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", include = JsonTypeInfo.As.PROPERTY)
@JsonSubTypes(value = {
        @JsonSubTypes.Type(value = Type1.class, name = "type1"),
        @JsonSubTypes.Type(value = Type2.class, name = "type2")
})
static public abstract class BaseType {
    public String type;
}
static public class Type1 extends BaseType {
    public String type1Specific;
    @Override
    public String toString() {
        return "Type1{" +
                "type1Specific='" + type1Specific + '\'' +
                '}';
    }
}
static public class Type2 extends BaseType {
    public String type2Specific;

    @Override
    public String toString() {
        return "Type2{" +
                "type2Specific='" + type2Specific + '\'' +
                '}';
    }
}

Here are the docs:

https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization

Hope this helps.

And the result would be:

[Type1{type1Specific='this is type1'}, Type2{type2Specific='this is type2'}]

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=415259&siteId=1