Java Jackson - 在反序列化时阻止float到int的转换

ABu*_*cin 8 java json jackson deserialization

我有一个JSON有效载荷,具有以下结构......

{
"age": 12
}
Run Code Online (Sandbox Code Playgroud)

...映射到以下类:

public class Student {

    private Integer age;

    public Integer getAge(){return age;}
    public void setAge(Integer age){this.age = age;}
}
Run Code Online (Sandbox Code Playgroud)

此时,如果用户为其提交浮点值age,则忽略小数,并且仅接受整数部分.我想要做的是阻止用户提交具有浮点值的有效负载age(见下文)并抛出异常(类似于"第8行第5行的字段'年龄'的无效JSON值" - 这是标准反序列化失败时的消息).

{
"age": 12.7 // will be truncated to 12
}
Run Code Online (Sandbox Code Playgroud)

我正在考虑为数值实现自定义反序列化器,但想知道是否有更简单的方法来实现这一点.

Jic*_*ang 11

切换ACCEPT_FLOAT_AS_INT.您可以访问https://github.com/FasterXML/jackson-databind/wiki/Deserialization-Features查看更多详细信息.


Bra*_*raj 7

setter使用可以检查值ObjectMapperreadValue()方法将json字符串转换为java对象时,将调用该方法.查看setter方法的签名,String而不是Integer.

示例代码:

class Student {

    private int age;    
    public int getAge() {
        return age;
    }

    public void setAge(String ageString) {
        System.out.println("called");
        try {
            age = Integer.parseInt(ageString);
        } catch (NumberFormatException e) {
           throw new IllegalArgumentException("age can't be in float");
        }
    }
}

...

try {
    Student student = new ObjectMapper().readValue("{\"age\": 12.5}", Student.class);
} catch (IllegalArgumentException e) {
    e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

  • 注意:此答案当时有效,但现在有一个功能标志,在另一个答案中标识,应该使用.IMO,默认情况下应该禁用该功能,因为它没有任何意义. (3认同)

Edu*_*Ros 6

默认情况下,从 Jackson 2.6 开始,浮点值将被截断为整数值。如上一个答案所示,设置ACCEPT_FLOAT_AS_INTfalse应该可以解决您的问题。

@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);
}
Run Code Online (Sandbox Code Playgroud)

  • 恕我直言,“ACCEPT_FLOAT_AS_INT”的默认值是“true”,这真的很奇怪。本来就不该如此。 (2认同)
  • https://fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/jackson/databind/DeserializationFeature.html。同意@Walter Tross,默认情况下此功能应设置为禁用 (2认同)