Jackson-databind 2.5, конвертирующий float в int

Что является альтернативой DeserializationFeature.ACCEPT_FLOAT_AS_INT в jackson -databind 2.5, так как эта конфигурация десериализации НЕ доступна в 2.5 (доступна с 2.6)

Наше приложение использует jackson-databind 2.5, в котором мы заметили, что float преобразуется в int.

Мы думаем, что нам нужно отключить преобразование значений, принуждение. Но так как мы используем Джексон 2.5, НЕТ DeserializationFeature.ACCEPT_FLOAT_AS_INT

Как отключить это преобразование float в int в 2.5? Мы ожидаем, что пользователь должен получить исключение для проверки данных, если он предоставляет float вместо int в "age".

Ниже приведен образец 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}

1 ответ

Измените свой класс User следующим образом:

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)
Другие вопросы по тегам