jackson杰森将一个对象反序列化为一个列表
我正在使用Spring的RestTemplate
和使用Jackson
反序列化来使用Web服务。
在我来自服务器的JSON响应中,其中一个字段可以是对象或列表。 意思是它可以是"result": [{}]
或"result": {}
。
有没有办法通过对我反序列化的类型的注释来处理这类事情? 将成员定义为array[]
或List
并在第二个示例的情况下插入单个对象? 我可以编写一个新的HttpMessageConverter
来处理它吗?
您可以使用Jackson的ObjectMapper
的配置标志来实现您想要的效果:
ObjectMapper mapper = Jackson2ObjectMapperBuilder.json() .featuresToEnable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY) .build();
只需按照本答案中的说明将此ObjectMapper
实例设置为RestTemplate
,并在要反序列化的类中,始终使用集合,即List
:
public class Response { private List result; // getter and setter }
既然你使用的是Jackson,我认为你需要的是JsonDeserializer
类( javadoc )。
您可以像这样实现它:
public class ListOrObjectGenericJsonDeserializer extends JsonDeserializer> { private final Class cls; public ListOrObjectGenericJsonDeserializer() { final ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass(); this.cls = (Class ) type.getActualTypeArguments()[0]; } @Override public List deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException, JsonProcessingException { final ObjectCodec objectCodec = p.getCodec(); final JsonNode listOrObjectNode = objectCodec.readTree(p); final List result = new ArrayList (); if (listOrObjectNode.isArray()) { for (JsonNode node : listOrObjectNode) { result.add(objectCodec.treeToValue(node, cls)); } } else { result.add(objectCodec.treeToValue(listOrObjectNode, cls)); } return result; } }
…
public class ListOrObjectResultItemJsonDeserializer extends ListOrObjectGenericJsonDeserializer {}
接下来,您需要注释您的POJO字段。 假设您有类似Result
和ResultItem
类:
public class Result { // here you add your custom deserializer so jackson will be able to use it @JsonDeserialize(using = ListOrObjectResultItemJsonDeserializer.class) private List result; public void setResult(final List result) { this.result = result; } public List getResult() { return result; } }
…
public class ResultItem { private String value; public String getValue() { return value; } public void setValue(final String value) { this.value = value; } }
现在您可以检查您的反序列化器:
// list of values final String json1 = "{\"result\": [{\"value\": \"test\"}]}"; final Result result1 = new ObjectMapper().readValue(json1, Result.class); // one value final String json2 = "{\"result\": {\"value\": \"test\"}}"; final Result result2 = new ObjectMapper().readValue(json2, Result.class);
result1
和result2
包含相同的值。