I use Jackson to deserialize a JSON to an immutable custom Java object. Here is the class:
final class DataPoint {
private final int count;
private final int median;
@JsonCreator
DataPoint(
@JsonProperty("count") int count,
@JsonProperty("median") int median) {
if (count <= 0) {
throw new IllegalArgumentException("...");
}
this.count = count;
this.median = median;
}
// getters...
}
Here is the JSON I deserialize:
{
"count": 1,
"median": 2
}
It works fine. Now, I break the JSON, i.e. replace the integer median
with the decimal:
{
"count": 1,
"median": 0.1
}
Now, I get count == 1
, and median == 0
. Instead, I would like the Jackson to fail deserilizing, since the data type of the JSON property median
and the formal median
parameter type (an int
) are different, and the conversion looses the data actually.
Here is the deserializing code:
String json = "..."; // the second JSON
ObjectMapper mapper = new ObjectMapper()
.enable(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES)
.enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)
.enable(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE);
DataPoint data = mapper.readValue(json, DataPoint.class);
Can I make Jackson fail when deserializing a decimal to an integer?
There is the option ACCEPT_FLOAT_AS_INT
for that purpose. E.g. :
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.ACCEPT_FLOAT_AS_INT);
And for "0.1"
you will get:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not coerce a floating-point value ('0.1') into Integer; enable
DeserializationFeature.ACCEPT_FLOAT_AS_INT
to allow
You can see pertinent docs here
Note that this is available since Jackson 2.6