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