Разбор массива неоднородных JSON объектов с Джексоном - PullRequest
3 голосов
/ 21 февраля 2020

У меня есть ситуация, когда мне нужно проанализировать массив JSON объектов, которые не идентичны.

Так, например:

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

Количество типов ограничено и содержимое каждого типа хорошо определено, но невозможно определить один тип объекта, который будет содержать содержимое.

Есть ли способ проанализировать их с Джексоном?

PS Я пытаюсь избежать написания собственного анализатора, если смогу помочь.

Ответы [ 2 ]

2 голосов
/ 12 марта 2020

Я бы использовал

com.fasterxml.jackson.databind.JsonNode.

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

В этом классе есть множество служебных методов для работы.

Или задайте c для массивов, которые вы можете использовать:

com.fasterxml.jackson.databind.node.ArrayNode

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

РЕДАКТИРОВАТЬ

Извините, я неправильно прочитал ваш вопрос, вы можете использовать @JsonTypeInfo для полиморфизма c сериализация / десериализация:

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 + '\'' +
                '}';
    }
}

Вот документы:

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

Надеюсь, это поможет.

И результат будет:

[Type1{type1Specific='this is type1'}, Type2{type2Specific='this is type2'}]
0 голосов
/ 12 марта 2020

Мы можем использовать List.class для сопоставления этого JSON массива с различными типами объектов, которые содержат контент. Он вернет список LinkedHashMaps. Различный контент будет сопоставлен с 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}] 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...