Search code examples
javajsonjacksondeserialization

Make the Jackson fail on converting double to int during deserialization


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?


Solution

  • 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