简体   繁体   English

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

[英]Ignore the “Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token” error

I am using an API from an external partner. 我正在使用外部合作伙伴提供的API。 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. 理想情况下,API合约意味着它不会被违反,但这种情况一直在发生。

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. 无论如何,所发生的事情是JSON响应中的一个字段主要是一个映射,但有时候,它是一个列表。

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. 但在极少数情况下,我会得到一个列表而不是地图或其他违反合同的行为。

For example: 例如:

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

I am using jackson to map this response to a POJO. 我正在使用杰克逊将这个回应映射到POJO。 In cases, when the contract is violated, I get the error, 如果违反合同,我会收到错误,

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token 线程“main”中的异常com.fasterxml.jackson.databind.JsonMappingException:无法从START_ARRAY令牌中反序列化java.util.LinkedHashMap的实例

In this case, I lose the information in the field majorInfo as well even though that adhered to the contract. 在这种情况下,即使遵守合同,我也会丢失majorInfo字段中的信息。 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. 在这种情况下,我的POJO的majorInfo成员将被正确设置,但minorInfo成员将为null。

I know about @JsonIgnoreProperties(ignoreUnknown = true) but that would always ignore the minorInfo field. 我知道@JsonIgnoreProperties(ignoreUnknown = true),但总会忽略minorInfo字段。 I would only like it to be ignored when the field does not adhere to the contract. 当该领域不遵守合同时,我只想忽略它。 Is that possible? 那可能吗?

I also tried 我也试过了

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

but this did not work either. 但这也行不通。

Is any other solution possible? 还有其他解决方案吗? The external partner is not going to change their API for us that is for sure. 外部合作伙伴不会为我们更改他们的API,这是肯定的。 So, any workable solution from our end? 那么,我们最终的任何可行的解决方案呢?

Thank you 谢谢

Edit: One solution is I have a POJO for both variants and put the code in a try catch block. 编辑:一个解决方案是我有两个变量的POJO并将代码放在try catch块中。 That may have worked if the JSON response had just one field that violated the contract and only in one particular way. 如果JSON响应只有一个违反合同的字段并且只有一种特定的方式,那么这可能有效。 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. 我不能继续尝试捕获块和第三次违规我已经意识到最好的办法是忽略违反它的字段。

I found a solution using the following thread as reference: Jackson: ignoring properties instead of throwing JsonMappingException 我找到了一个使用以下线程作为参考的解决方案: Jackson:忽略属性而不是抛出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;
    }

}

You can write your own java method for transforming an input json to a "standard" json that adheres to the contract, and then use Jackson on it. 您可以编写自己的java方法,将输入json转换为符合合同的“标准”json,然后在其上使用Jackson。

something along the lines of: 类似的东西:

private String transform(String input)
{
    String result = input;

    if (result.contains("\"minorInfo\" : []"))
    {
        result = result.replace("\"minorInfo\" : []", "");
    }

    return result;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法从我的“DataRequests”dto 中的 START_ARRAY 令牌中反序列化 java.util.LinkedHashMap 的实例 - Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token in my 'DataRequests' dto 使用Jackson反序列化JSON时出错:无法从START_ARRAY令牌中反序列化java.util.LinkedHashMap实例 - Error while deserializing JSON using Jackson : Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token 错误:无法在 [来源:N/A; 行:-1,列:-1] - Error: Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token at [Source: N/A; line: -1, column: -1] 无法使用 JsonAvroConverter 从 START_ARRAY 中反序列化 java.util.LinkedHashMap 的实例 - Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY with JsonAvroConverter JSON到XML转换中的错误:无法从START_ARRAY令牌中反序列化java.util.HashMap的实例 - error in JSON to XML conversion: Can not deserialize instance of java.util.HashMap out of START_ARRAY token 无法将Java文件中的JSON文件转换为hashmap并出现错误,无法从START_ARRAY令牌中反序列化java.util.HashMap的实例 - convert JSON file to a hashmap in java with error Can not deserialize instance of java.util.HashMap out of START_ARRAY token 无法从 START_ARRAY 令牌反序列化 java.util.HashMap 的实例 - Can not deserialize instance of java.util.HashMap out of START_ARRAY token 无法使用START_ARRAY令牌反序列化对象实例 - Can not deserialize instance of object out of START_ARRAY token 无法反序列化实例,超出 START_ARRAY 令牌 - Can not deserialize instance, out of START_ARRAY token 无法从START_ARRAY标记中反序列化Task的实例 - Can not deserialize instance of Task out of START_ARRAY token
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM