忽略“无法从START_ARRAY令牌中反序列化java.util.LinkedHashMap的实例”错误

我正在使用来自外部合作伙伴的API。 不幸的是,返回的响应似乎没有固定的结构。 理想情况下,API合约意味着它不会被违反,但这种情况一直在发生。

无论如何,所发生的事情是JSON响应中的一个字段主要是一个映射,但有时候,它是一个列表。

例如,假设以下是我通常得到的响应:

{ "majorInfo" : { "a" : "b" }, "minorInfo" : { "c" : "d" } } 

但在极少数情况下,我会得到一个列表而不是地图或其他违反合同的行为。

例如:

 { "majorInfo" : { "a" : "b" }, "minorInfo" : [] } 

我正在使用jackson将这个回应映射到POJO。 如果违反合同,我会收到错误,

线程“main”中的exceptioncom.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响应只有一个违反合同的字段并且只有一种特定的方式,那么这可能有效。 我实际得到的回应是巨大的,这是我在第三场比赛中发现的第三次违规。 我不能继续尝试捕获块和第三次违规我已经意识到最好的办法是忽略违反它的字段。

我找到了一个使用以下线程作为参考的解决方案: Jackson:忽略属性而不是抛出JsonMappingException

我写了一个自定义反序列化器并用它来忽略错误。

 public class CustomListingDeserializer extends JsonDeserializer>{ public CustomListingDeserializer() { // TODO Auto-generated constructor stub } @Override public Map deserialize(JsonParser arg0, DeserializationContext arg1) throws IOException, JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); JsonNode node = arg0.readValueAsTree(); try { return mapper.readValue(node.toString(), new TypeReference>(){}); } 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; } } 

您可以编写自己的java方法,将输入json转换为符合合同的“标准”json,然后在其上使用Jackson。

类似的东西:

 private String transform(String input) { String result = input; if (result.contains("\"minorInfo\" : []")) { result = result.replace("\"minorInfo\" : []", ""); } return result; }