Ignore the "Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token" error

Paagalpan

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.

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.

For example:

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

I am using jackson to map this response to a 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

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.

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?

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. 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. 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.

Paagalpan

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

}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related