Parsing an array of non-homogeneous JSON Objects with Jackson

﹥>﹥吖頭↗ 提交于 2021-02-18 16:43:36

问题


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.


回答1:


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'}]



回答2:


We can use List.class to map this JSON Array with different types of objects that hold the content. It will return the List of LinkedHashMaps. Different content will be mapped to LinkedHashMap.

@Test
public void testLoadCustom() {
    String json = "[{\"a\":\"A\" } , {\"b\":\"B\" , \"c\":\"C\" } , {\"d\":\"D\" } ]";
    try {
        List custom = objectMapper.readValue(json, List.class);
        System.out.println(custom);
    } catch (Exception ex) {
        ex.getStackTrace();
    }
}


 // Output [{a=A}, {b=B, c=C}, {d=D}] 


来源:https://stackoverflow.com/questions/60329302/parsing-an-array-of-non-homogeneous-json-objects-with-jackson

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!