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)