使用Jackson进行反序列化时阻止float到int的转换

lf5gs5x2  于 2022-11-08  发布在  其他
关注(0)|答案(3)|浏览(306)

我有一个JSON有效负载,其结构如下:

{
"age": 12
}

它被Map到以下类:

public class Student {

    private Integer age;

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

此时,如果用户提交age的浮点值,小数部分被忽略,只接受整数部分。我想做的是防止用户提交age的浮点值有效负载(见下文)并抛出异常(类似于“第8行第5列的字段”age“的JSON值无效”-这是反序列化失败时的标准消息)。

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

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

yr9zkbsy

yr9zkbsy2#

当使用ObjectMapperreadValue()方法将json字符串转换为java对象时,将调用setter方法,在readValue()方法中您可以检查值。请查看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();
}
57hvy0tb

57hvy0tb3#

默认情况下,从Jackson2.6开始,浮点值将被截断为整数值。如前一个答案所示,将ACCEPT_FLOAT_AS_INT设置为false应该可以解决您的问题。

@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);
}

相关问题