Java – jackson parses integers as double

jackson parses integers as double… here is a solution to the problem.

jackson parses integers as double

ENVIRONMENTS: JACKSON 2.8.10 AND SPRING BOOT 1.5.10.RELEASE

In the JSON request, I receive the following:

{
  total: 103
}

In other cases, the total may have decimal precision, for example: 103.25. I WOULD LIKE TO BE ABLE TO USE JACKSON

FOR BOTH CASES

In my Java, I want to read this 103 into a double:

Configuration conf = Configuration.builder().mappingProvider(new JacksonMappingProvider())
                .jsonProvider(new JacksonJsonProvider()).build();
Object rawJson = conf.jsonProvider().parse(payload);
double listPrice = JsonPath.read(rawJson, "$.total")

But then I get the following error:

Java.lang.Integer cannot be cast to java.lang.Double.

Is there a way to handle the above without string/math manipulation?

Solution

Is there a way to handle the case above without doing string/mathematical manipulations?

This should be done.

Configuration conf = Configuration.builder()
       .mappingProvider(new JacksonMappingProvider())
       .jsonProvider(new JacksonJsonProvider())
       .build();
Object rawJson = conf.jsonProvider().parse(payload);
Object rawListPrice = JsonPath.read(rawJson, "$.total");
double listPrice;
if (rawListPrice instanceOf Double) {
    listPrice = (Double) rawListPrice;
} else if (rawListPrice instanceOf Integer) {
    listPrice = (Integer) rawListPrice;
} else {
    throw new MyRuntimeException("unexpected type: " + rawListPrice.getClass());
}

If you want to do this repeatedly, create a method….

public double toDouble(Object number) {
    if (number instanceof Double) {
        return (Double) number;
    } else if (number instanceof Integer) {
        return (Integer) number;
    } else {
        throw new MyRuntimeException("unexpected type: " + number.getClass());
    }
}

The root cause of the exception is that the return type of JsonPath.read is an unconstrained type parameter. The compiler infers this to whatever type the calling site expects and adds a hidden type conversion to ensure that the actual value returned is of the expected type.

The problem arises when JsonPath.read can actually return multiple types in a single call. The compiler has no way of knowing what it can return… Or how to convert it.

Solution: Handle conversions with some runtime type checking.


Here’s another solution that should work:

double listPrice = ((Number) JsonPath.read(rawJson, "$.total")).doubleValue();

… If the value of “total” in JSON is (say) a string, you still get a modulus of ClassCastException.

Related Problems and Solutions