问题描述
我找到了一个使用以下线程作为参考的解决方案:Jackson:忽略属性,而不是抛出JsonMappingException
public class CustomListingDeserializer extends JsonDeserializer<Map<String, Listing>>{
public CustomListingDeserializer() {
// TODO Auto-generated constructor stub
}
@Override
public Map<String, Listing> deserialize(JsonParser arg0, DeserializationContext arg1)
throws IOException, JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
JsonNode node = arg0.readValueAsTree();
try
{
return mapper.readValue(node.toString(), new TypeReference<Map<String,Listing>>(){});
}
catch (JsonMappingException e)
{
System.out.println("Issue in deserializing : " + e.getMessage() + "for :" + node.toString());
}
catch (Exception e)
{
throw e;
}
// TODO Auto-generated method stub
return null;
}
}
解决方法
我正在使用来自外部合作伙伴的API。不幸的是,返回的响应似乎没有固定的结构。理想情况下,API合同意味着它不会被违反,但是这种情况一直在发生。
无论如何,所以发生的事情是JSON响应中的字段主要是一个地图,但有时却是一个列表。
例如,假设以下是我通常得到的响应:
{
"majorInfo" : {
"a" : "b"
},"minorInfo" : {
"c" : "d"
}
}
但是在极少数情况下,我会得到列表,而不是地图或其他违反合同的情况。
例如:
{
"majorInfo" : {
"a" : "b"
},"minorInfo" : []
}
我正在使用杰克逊将此响应映射到POJO。在某些情况下,如果违反合同,我会收到错误消息,
线程“主”中的异常com.fasterxml.jackson.databind.JsonMappingException:无法从START_ARRAY令牌中反序列化java.util.LinkedHashMap实例
在这种情况下,即使遵守合同,我也会丢失majorInfo字段中的信息。如果某个字段不遵守合同,有什么办法可以忽略它?在这种情况下,将正确设置我的POJO的majorInfo成员,但minorInfo成员将为null。
我知道@JsonIgnoreProperties(ignoreUnknown = true),但这 始终
会忽略minorInfo字段。我只希望在不遵守合同的情况下忽略它。那可能吗?
我也试过
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
但这也不起作用。
还有其他解决方案吗?可以肯定的是,外部合作伙伴不会为我们更改其API。那么,从我们的角度来看,任何可行的解决方案?
谢谢
编辑:一种解决方案是我对两个变体都有一个POJO,并将代码放入try
catch块中。如果JSON响应只有一个违反合同且仅以一种特定方式违反的字段,那可能会起作用。我实际上得到的回应是巨大的,这是我在第三方面遇到的第三次违规。我不能再继续尝试尝试阻拦了,由于第三次违规,我意识到最好的选择就是忽略违反它的字段。