忽略“无法从START_ARRAY标记中反序列化java.util.LinkedHashMap的实例”错误 [英] Ignore the "Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token" error

查看:796
本文介绍了忽略“无法从START_ARRAY标记中反序列化java.util.LinkedHashMap的实例”错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using an API from an external partner. Unfortunately, the returned response does not seem to have a fixed structure. Ideally, an API contract means it won't be violated but this keeps happening.

无论如何,所发生的事情是JSON响应中的一个字段主要是一张地图但是有时候,它是一个清单。

Anyways, so what is happening is a field in the JSON response is mostly a map but sometimes, out of the blue it is a list.

例如,假设以下是我通常得到的回复:

For example, suppose that following is the response I usually get:

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

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

But on rare occasion I'd get a list instead of a map or some other violation of the contract.

例如:

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

我使用jackson将此响应映射到POJO。在违反合同的情况下,我收到错误,

I am using jackson to map this response to a POJO. In cases, when the contract is violated, I get the error,


线程main
com.fasterxml中的异常。 jackson.databind.JsonMappingException:不能
反序列化java.util.LinkedHashMap的实例超出START_ARRAY
令牌

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token

在这种情况下,即使遵守合同,我也会丢失majorInfo字段中的信息。有什么方法可以在不遵守合同时忽略某个领域?在这种情况下,我的POJO的majorInfo成员将被正确设置但minorInfo成员将为null。

In this case, I lose the information in the field majorInfo as well even though that adhered to the contract. Is there any way that I can ignore a field when it does not adhere to the contract? In this case, majorInfo member of my POJO would be correctly set but minorInfo member would be null.

我知道@JsonIgnoreProperties(ignoreUnknown = true)但是 >始终忽略minorInfo字段。当该领域不遵守合同时,我只想忽略它。这可能吗?

I know about @JsonIgnoreProperties(ignoreUnknown = true) but that would always ignore the minorInfo field. I would only like it to be ignored when the field does not adhere to the contract. Is that possible?

我也试过了

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

但这也不起作用。

还有其他解决方案吗?外部合作伙伴不会为我们更改他们的API。那么,我们最终的解决方案是什么?

Is any other solution possible? The external partner is not going to change their API for us that is for sure. So, any workable solution from our end?

谢谢

编辑:
一个解决方案是我有两个变量的POJO并将代码放在try catch块中。如果JSON响应只有一个违反合同的字段并且只有一种特定的方式,那么这可能有效。我实际得到的回应是巨大的,这是我在第三场比赛中发现的第三次违规。我不能继续尝试使用try catch块,并且通过第三次违规我已经意识到最好的办法是忽略违反它的字段。

One solution is I have a POJO for both variants and put the code in a try catch block. That may have worked if the JSON response had just one field that violated the contract and only in one particular way. The response I'm actually getting is huge and this is the third violation I have caught on a third field. I can't keep putting try catch blocks and by the third violation I've realized the best bet is to just ignore the fields violating it.

推荐答案

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

I found a solution using the following thread as reference: Jackson: ignoring properties instead of throwing JsonMappingException

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

I wrote a custom deserializer and used it to ignore errors.

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;
    }

}

这篇关于忽略“无法从START_ARRAY标记中反序列化java.util.LinkedHashMap的实例”错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆