jackson真的无法将json反序列化成generics?
这是一个重复的问题,因为下面的问题要么混乱,要么根本没有答案:
反序列化-A-通用型与jackson
jackson反序列化-到-运行指定的类
用jackson反序列化,generics类
jackson反序列化generics类variables
我希望这个问题能够最终find一个让问题清楚的答案。
有一个模型:
public class AgentResponse<T> { private T result; public AgentResponse(T result) { this.result = result; } public T getResult() { return result; } }
JSONinput:
{"result":{"first-client-id":3,"test-mail-module":3,"third-client-id":3,"second-client-id":3}}
以及两种推荐的对generics进行反序列化的方法:
mapper.readValue(out, new TypeReference<AgentResponse<Map<String, Integer>>>() {});
要么
JavaType javaType = mapper.getTypeFactory().constructParametricType(AgentResponse.class, Map.class); mapper.readValue(out, javaType);
jackson永远不能处理genericstypesT,它认为它是一个来自JavaType的Map,但是由于types擦除,它findObjecttypes的构造函数参数,并引发错误。 那么这是一个jackson错误,还是我做错了什么? 还有什么明确的TypeReference或JavaType规范?
com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.fg.mail.smtp.AgentResponse<java.util.Map<java.lang.String,java.lang.Integer>>]: can not instantiate from JSON object (need to add/enable type information?) at [Source: java.io.InputStreamReader@4f2d26d; line: 1, column: 2] at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:984) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:276) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2064)
您需要在构造函数中添加一些注释以告诉Jackson如何构build该对象。 以下为我工作:
public class AgentResponse<T> { private T result; @JsonCreator public AgentResponse(@JsonProperty("result") T result) { this.result = result; } public T getResult() { return result; } }
没有@JsonCreator
注解,jackson不知道调用这个构造函数。 没有@JsonProperty
注释,Jackson不知道构造函数的第一个参数映射到result
属性。
我尝试使用相同的方法,但我没有注释我的模型类。 它为我工作得很好。
这是我的模特class
public class BasicMessage<T extends Serializable> implements Message<T> { private MessageHeader messageHeader = new MessageHeader(); private T payload; public MessageHeader getHeaders() { return messageHeader; } public Object getHeader(String key) { return messageHeader.get(key); } public Object addHeader(String key, Object header) { return messageHeader.put(key, header); } public T getPayload() { return payload; } public void setPayload(T messageBody) { this.payload = messageBody; } }
我使用下面的方法来反序列化有效载荷
public static <T extends Serializable> BasicMessage<T> getConcreteMessageType(String jsonString, Class<T> classType) { try { ObjectMapper mapper = new ObjectMapper(); JavaType javaType = mapper.getTypeFactory().constructParametricType(BasicMessage.class, classType); return mapper.readValue(jsonString, javaType); } catch (IOException e) { } }
其中jsonString包含string中的BasicMessageObject。