0

jackson-databind 2.5中 DeserializationFeature.ACCEPT_FLOAT_AS_INT 的替代品是什么,因为此反序列化配置在2.5中不可用(自2.6起可用)

我们的应用程序正在使用 jackson-databind 2.5,其中我们注意到 float 正在转换为 int。

我们虽然需要禁用值转换,强制。但是当我们使用杰克逊 2.5 时,没有DeserializationFeature.ACCEPT_FLOAT_AS_INT

如何在 2.5 中禁用此 float 到 int 的转换?如果用户在“age”中提供 float 而不是 int,我们希望用户应该得到数据验证异常。

以下是示例 POJO

public class User {

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }

}

这是测试代码(使用 jackson-databind 2.5):

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestConvert {

    public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {

        ObjectMapper mapper = new ObjectMapper();
        String json = "{\"name\" : \"foobar\", \"age\" : 2.99}";

        //JSON from file to Object
        User user = mapper.readValue(json, User.class);

        //Object to JSON in String
        String jsonInString = mapper.writeValueAsString(user);
        System.out.println(jsonInString);


    }

}

上述测试代码的输出为:

{“名称”:“foobar”,“年龄”:2}

4

1 回答 1

0

像这样更改您的用户类:

package ch.hasselba.jackson.test2;

import com.fasterxml.jackson.databind.JsonMappingException;

public class User {

    private String name;
    private int age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(Object age) throws JsonMappingException {

        if( age instanceof Float )
            throw new com.fasterxml.jackson.databind.JsonMappingException("Bad Age! No Floats allowed!");
        if( age instanceof Double )
            throw new com.fasterxml.jackson.databind.JsonMappingException("Bad Age! No Doubles please!");

        this.age = (Integer) age;
    }

}

您将收到如下错误:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Bad Value! No Doubles please
 at [Source: {"name" : "foobar", "age" : 2.99}; line: 1, column: 29] (through reference chain: ch.hasselba.jackson.test2.User["age"])
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:268)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:537)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty._throwAsIOE(SettableBeanProperty.java:518)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:99)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:276)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:140)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3789)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2833)
    at ch.hasselba.jackson.test2.TestConvert.main(TestConvert.java:19)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Bad Value! No Doubles please
    at ch.hasselba.jackson.test2.User.setAge(User.java:24)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:97)
    ... 5 more

Jackson 2.8.0 和禁用的DeserializationFeature.ACCEPT_FLOAT_AS_INT的错误如下所示:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Can not coerce a floating-point value ('2.99') into Integer; enable `DeserializationFeature.ACCEPT_FLOAT_AS_INT` to allow
 at [Source: {"name" : "foobar", "age" : 2.99}; line: 1, column: 29] (through reference chain: ch.hasselba.jackson.test2.User["age"])
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:261)
    at com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1233)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer._failDoubleToIntCoercion(StdDeserializer.java:1118)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseInteger(StdDeserializer.java:430)
    at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:308)
    at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:286)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:490)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:276)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:140)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3789)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2833)
    at ch.hasselba.jackson.test2.TestConvert.main(TestConvert.java:19)
于 2017-02-13T11:04:28.100 回答