Jackson deserialization of type with different objects

前端 未结 4 1559
清酒与你
清酒与你 2020-12-06 02:21

I have a result from a web service that returns either a boolean value or a singleton map, e.g.

Boolean result:

{
    id: 24428,
    rated: false
}
<         


        
4条回答
  •  悲哀的现实
    2020-12-06 02:47

    You have to write your own deserializer. It could look like this:

    @SuppressWarnings("unchecked")
    class RatingJsonDeserializer extends JsonDeserializer {
    
        @Override
        public Rating deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            Map map = jp.readValueAs(Map.class);
    
            Rating rating = new Rating();
            rating.setId(getInt(map, "id"));
            rating.setRated(getRated(map));
    
            return rating;
        }
    
        private int getInt(Map map, String propertyName) {
            Object object = map.get(propertyName);
    
            if (object instanceof Number) {
                return ((Number) object).intValue();
            }
    
            return 0;
        }
    
        private int getRated(Map map) {
            Object object = map.get("rated");
            if (object instanceof Boolean) {
                if (((Boolean) object).booleanValue()) {
                    return 0; // or throw exception
                }
    
                return -1;
            }
    
            if (object instanceof Map) {
                return getInt(((Map) object), "value");
            }
    
            return 0;
        }
    }
    

    Now you have to tell Jackson to use this deserializer for Rating class:

    @JsonDeserialize(using = RatingJsonDeserializer.class)
    class Rating {
    ...
    }
    

    Simple usage:

    ObjectMapper objectMapper = new ObjectMapper();
    System.out.println(objectMapper.readValue(json, Rating.class));
    

    Above program prints:

    Rating [id=78, rated=10]
    

    for JSON:

    {
        "id": 78,
        "rated": {
            "value": 10
        }
    }
    

    and prints:

    Rating [id=78, rated=-1]
    

    for JSON:

    {
        "id": 78,
        "rated": false
    }
    

提交回复
热议问题