Java Jackson在泛型列表中读取json

Java Jackson在泛型列表中读取json,java,json,list,jackson,Java,Json,List,Jackson,我使用Jackson来读取json消息。我试图解析的一个值是一个列表,另一个值包含列表中的数据类型。这是我用java创建的结构 public class Message<T> { private Timestamp time; private RestAction action; private String type; private List<T> data; } 公共类消息{ 私有时间戳时间; 私人重新行动; 私有字符串类型; 私人名单数据

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

public class Message<T> {
   private Timestamp time;
   private RestAction action;
   private String type;
   private List<T> data;
}
公共类消息{
私有时间戳时间;
私人重新行动;
私有字符串类型;
私人名单数据;
}

通过
Class.forName()我可以得到表示列表中数据的类。问题是我怎样才能阅读这份清单

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

public class MessageDeserializer extends JsonDeserializer<Message> {
  @Override
  public Message deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
    throws IOException, JsonProcessingException {
    // YOU DESERIALIZER CODE HERE
  }
}
公共类MessageDeserializer扩展JsonDeserializer{
@凌驾
公共消息反序列化(JsonParser JsonParser,反序列化上下文反序列化上下文)
抛出IOException、JsonProcessingException{
//您可以在这里输入反序列化程序代码
}
}

@请参阅此处的示例:

如果需要将传入的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);
String jsonString=//您传入的json字符串
ObjectMapper mapper=新的ObjectMapper();
Class clz=Class.forName(您的类型字符串);
JavaType type=mapper.getTypeFactory().ConstructionCollectionType(List.class,clz);
列表结果=mapper.readValue(jsonString,类型);
编辑

像这样的事情,完全没有经过测试,从来没有做过

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;
}
公共消息反序列化(JsonParser JsonParser,反序列化上下文arg1)
抛出IOException、JsonProcessingException{
ObjectMapper mapper=新的ObjectMapper();
ObjectCodec oc=jsonParser.getCodec();
JsonNode=oc.readTree(jsonParser);
JsonNode timeStamp=node.get(“时间”);
Timestamp time=mapper.readValue(Timestamp,Timestamp.class);
JsonNode restAction=node.get(“操作”);
RestAction action=mapper.readValue(RestAction,RestAction.class);
字符串类型=node.get(“type”).getTextValue();
Class clz=Class.forName(类型);
JsonNode list=node.get(“数据”);
JavaType listType=mapper.getTypeFactory().constructCollectionType(List.class,clz);
列表数据=mapper.readValue(列表,列表类型);
消息消息=新消息;
message.setTime(时间);
message.setAction(action);
message.setType(类型);
message.setData(数据);
返回消息;
}

短得多的东西:

mapper.readValue(jsonString, new TypeReference<List<EntryType>>() {});
mapper.readValue(jsonString,newTypeReference(){});
其中,
EntryType
是对您希望在集合中保留的类型的引用。它可能是任何Java类。
例如,要读取JSON表示,例如
[“a”、“b”、“c”]
映射器的第二个参数应该是
new TypeReference(){}

,如果您需要在泛型列表中读取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);
TypeReference personList=newtypereference(){};
ObjectMapper ObjectMapper=新的ObjectMapper();
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.configure(在未知属性上反序列化feature.FAIL,false);
HashMap employees=objectMapper.readValue(request.getInputStream(),personList);
自2.11版(2020年4月)以来,Jackson拥有
readerForListOf
method():

ObjectMapper-mapper=ObjectMapper().configure(…);
ObjectReader=mapper.readerForListOf(MyClass.class);
List=reader.readValue(…);

好的……我已经尝试过这样解决问题,但问题是除了列表之外,json消息还有其他字段。糟糕,我不明白你的问题。然后你需要像seralex.vi说的那样创建一个反序列化程序。你可以在它里面使用类似的东西来反序列化我的答案,让我知道它是否有效,我可能很快就会为答案做类似的事情…实际上,将你的答案和seralex的答案结合起来帮助我解决了这个问题(写一些类似于你编辑的答案的东西)。没有机会尝试,因为其他问题,但我认为这部分已经完成。又来了!您能向我们展示您已经编写的示例JSON字符串和源代码吗?我想你也可以看到这个问题:如果你不介意的话,请把我的答案标记为有效答案,因为我得到了大部分的分数。它结构紧凑,完全满足您的需要,非常有效。还可以尝试这样做:迭代器it=mapper.reader(Objects.class).readValues(in);Objects.class来自何处?它属于列表中的类型(示例中的EntryType)。此答案没有说明
EntryType
来自何处!
ObjectMapper mapper = ObjectMapper().configure(...);
ObjectReader reader = mapper.readerForListOf(MyClass.class);
List<MyClass> list = reader.readValue(...);