35

我正在使用 Jackson 来阅读 json 消息。我试图解析的值之一是 List,另一个值包含列表中数据的类型。这是我在 java 中创建的结构。

public class Message<T> {
   private Timestamp time;
   private RestAction action;
   private String type;
   private List<T> data;
}

通过Class.forName();我可以得到代表列表中数据的类。问题是我如何阅读列表。

4

5 回答 5

97

更短的东西:

mapper.readValue(jsonString, new TypeReference<List<EntryType>>() {});

EntryType您希望在集合中保存的类型的引用在哪里。它可能是任何 Java 类。例如,要读取 JSON 表示,例如["a", "b", "c"] mapper 的第二个参数应该是new TypeReference<List<String>>() {}

于 2013-12-05T11:19:56.390 回答
65

如果您需要将传入的 json 映射到您的列表,您可以这样做

String jsonString = ...; //Your incoming json string
ObjectMapper mapper = new ObjectMapper();
Class<?> clz = Class.forName(yourTypeString);
JavaType type = mapper.getTypeFactory().constructCollectionType(List.class, clz);
List <T> result = mapper.readValue(jsonString, type);

编辑

像这样的东西,完全未经测试,从未做过

public Message<T> deserialize(JsonParser jsonParser, DeserializationContext arg1)
    throws IOException, JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    ObjectCodec oc = jsonParser.getCodec();
    JsonNode node = oc.readTree(jsonParser);

    JsonNode timeStamp = node.get("time");
    Timestamp time = mapper.readValue(timeStamp, Timestamp.class);
    JsonNode restAction = node.get("action");
    RestAction action = mapper.readValue(restAction, RestAction.class);
    String type = node.get("type").getTextValue();
    Class<?> clz = Class.forName(type);
    JsonNode list = node.get("data");
    JavaType listType = mapper.getTypeFactory().constructCollectionType(List.class,   clz);
    List <T> data = mapper.readValue(list, listType);

    Message<T> message = new Message<T>;
    message.setTime(time);
    message.setAction(action);
    message.setType(type);
    message.setData(data);

    return message;
}
于 2013-07-31T20:00:53.173 回答
4

您需要使用@JsonDeserialize(using = MessageDeserializer.class)自定义反序列化器注释您的类并实现:

public class MessageDeserializer extends JsonDeserializer<Message> {
  @Override
  public Message deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
    throws IOException, JsonProcessingException {
    // YOU DESERIALIZER CODE HERE
  }
}

@参见此处的示例:如何编写 Jackson JSON 序列化器和反序列化器?

于 2013-07-31T19:48:50.650 回答
2

自 2.11 版(2020 年 4 月)以来,杰克逊有readerForListOf方法(文档):

ObjectMapper mapper = ObjectMapper().configure(...);
ObjectReader reader = mapper.readerForListOf(MyClass.class);
List<MyClass> list = reader.readValue(...);
于 2021-05-06T10:47:53.040 回答
-2

如果您需要在通用列表中读取 json,请执行类似的操作

{
    Employee:
    [
        {
            "key": "value",
            "key": "value"
        },
        {
            "key": "value",
            "key": "value"
        }
    ]
} 

你的 json 列表对象和你的 bean 类是

class person {
private String key;
private String value;
}

现在您可以使用 HashMap 读取此 json

就像是

TypeReference<HashMap<String,List<Person>>> personList =  new   TypeReference<HashMap<String, List<Person>>>() {};

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

HashMap<String, List<Person>> employees = objectMapper.readValue(request.getInputStream(), personList);
于 2016-06-29T06:03:37.263 回答