Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Jackson - prevent float to int conversion when deserializing

I have a JSON payload with the following structure ...

{
"age": 12
}

... which is mapped to the following class:

public class Student {

    private Integer age;

    public Integer getAge(){return age;}
    public void setAge(Integer age){this.age = age;}
}

At the moment, if the user submits a float value for the age, the decimals are ignored and the only the integer part is accepted. What I want to do is prevent the user from submitting a payload with a float value for the age (see below) and throw an exception (something like "invalid JSON value for field 'age' at line 8 col 5" - as is the standard message when deserialization fails).

{
"age": 12.7 // will be truncated to 12
}

I was thinking of implementing a custom deserializer for numeric values but was wondering if there is a simpler way to achieve this.

like image 768
ABucin Avatar asked Aug 01 '14 08:08

ABucin


People also ask

What happens when float is converted to int?

To convert a float value to int we make use of the built-in int() function, this function trims the values after the decimal point and returns only the integer/whole number part. Example 1: Number of type float is converted to a result of type int.

Does Jackson use Java serialization?

Note that Jackson does not use java.

Can a float be cast into an int?

Since a float is bigger than int, you can convert a float to an int by simply down-casting it e.g. (int) 4.0f will give you integer 4. By the way, you must remember that typecasting just get rid of anything after the decimal point, they don't perform any rounding or flooring operation on the value.

Can you cast a float to an int in Java?

Java allows you to cast, or convert a variable of one type to another; in this case, cast a float to an int. This option removes all digits to the right of the decimal place. Another option is to use the Math. round method to round the value to the nearest integer.


2 Answers

A floating-point value will be truncated to an integer value by default from Jackson 2.6. As indicated in a previous answer, setting ACCEPT_FLOAT_AS_INT to false should fix your problem.

@Test(expected = JsonMappingException.class)
public void shouldFailMarshalling() throws IOException {
    final String student = "{\"age\": 12.5}";
    final ObjectMapper mapper = new ObjectMapper();

    // don't accept float as integer
    mapper.configure(ACCEPT_FLOAT_AS_INT, false);
    mapper.readValue(student, Student.class);
}
like image 132
Eduardo Sanchez-Ros Avatar answered Oct 13 '22 05:10

Eduardo Sanchez-Ros


Toggle off ACCEPT_FLOAT_AS_INT. You can check more details at https://github.com/FasterXML/jackson-databind/wiki/Deserialization-Features

like image 23
Jichao Zhang Avatar answered Oct 13 '22 05:10

Jichao Zhang