[英]Jackson Serialization and Deserialization of java.lang.Number Extensions
I am trying to use Jackson to serialize and deserialize a custom numeric class that extends java.lang.Number
. 我正在尝试使用Jackson来序列化和反序列化扩展
java.lang.Number
的自定义数字类。 Below is a barebones implementation of the class without extending Number
. 下面是该类的准系统实现,而没有扩展
Number
。
import com.google.common.primitives;
public class UnsignedNumericClass {
private long data;
public UnsignedNumericClass(long data) {
this.data = data;
}
public UnsignedNumericClass(String data) {
this.data = UnsignedLongs.decode(data);
}
public UnsignedNumericClass() {}
public void setData(long data) {this.data = data;}
public long getData() {return data;}
public toString() {return UnsignedLongs.toString(data);}
public int intValue() {return (int) data;}
public long longValue() {return data;}
public float floatValue() {return data;}
public double doubleValue() {return data;}
}
This plays very well with Jackson, however the second I change the class to read 这与杰克逊玩得非常好,但是第二次我将课程改为阅读
public class UnsignedNumericClass extends Number
Jackson fails to deserialize claiming "No suitable creator method found to deserialize from Number value (14169630718280903901)". Jackson未能反序列化,声称“找不到从Number值反序列化的合适的创建者方法(14169630718280903901)”。 Additionally, it only fails sometimes.
此外,它有时仅会失败。
Does anyone know why this is happening or how to make Jackson successfully deserialize to an instance of a class that extends java.lang.Number
? 有谁知道为什么会这样或如何使Jackson成功反序列化为扩展
java.lang.Number
的类的实例?
davidxxx was indeed right that deserialization was only failing when the serialized number was greater than Long.MAX_VALUE
. davidxxx确实是对的,只有当序列号大于
Long.MAX_VALUE
时,反序列化才会失败。 The problem runs a little deeper than that though. 问题比这更深。
When UnsignedNumericClass
does not extend Number
, Jackson treats it as an ordinary object and serializes/deserializes via getters, setters, and the default constructor UnsignedNumericClass()
. 当
UnsignedNumericClass
不扩展Number
,Jackson会将其视为普通对象,并通过getter,setter和默认构造函数UnsignedNumericClass()
序列化/反序列化。
Once UnsignedNumericClass
extends Number
, Jackson changes to serialize/deserialize via toString()
and the String-argument constructor UnsignedNumericClass(String data)
. 一旦
UnsignedNumericClass
扩展Number
,Jackson便会通过toString()
和String参数构造函数UnsignedNumericClass(String data)
进行序列化/反序列化。 Note that an exception will be thrown if a String-argument constructor does not exist. 请注意,如果不存在字符串参数构造函数,则将引发异常。
I was experiencing the questioned issue because I am implementing an unsigned 64-bit number. 我遇到了一个问题,因为我正在实现一个无符号的64位数字。 Because the number is unsigned, my
toString()
implementation prints the unsigned interpretation of the private long data
field. 因为数字是无符号的,所以我的
toString()
实现打印了private long data
字段的无符号解释。
When deserializing numeric types, Jackson performs a check to make sure that it is a valid number. 反序列化数字类型时,Jackson会执行检查以确保它是有效数字。 That is, it checks if the number given in the JSON document is less than
Long.MAX_VALUE
. 也就是说,它检查JSON文档中给定的数字是否小于
Long.MAX_VALUE
。 If this is not the case, it relies on a custom deserializer instead of just using my String-argument constructor which could handle the number just fine. 如果不是这种情况,则它依赖于自定义反序列化器,而不仅仅是使用我的String-argument构造函数,该构造函数可以很好地处理数字。 Since no custom deserializer is specified, it throws the "no suitable creator method" exception.
由于未指定自定义反序列化器,因此它将引发“没有合适的创建者方法”异常。 Therefore the solution is to define a simple custom deserializer that uses the String-argument constructor:
因此,解决方案是定义一个简单的自定义反序列化器,该反序列化器使用String-argument构造函数:
public class CustomDeserializer extends StdDeserializer<UnsignedNumericClass> {
public CustomDeserializer(){super(null);}
public CustomDeserializer(Class<?> c){super(c);}
public UnsignedNumericClass deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException{
return new UnsignedNumericClass(jsonParser.getText());
}
Then we specify to Jackson to use this deserializer via the @JsonDeserialize()
annotation: 然后,我们通过
@JsonDeserialize()
注释指定Jackson使用此反序列化器:
@JsonDeserialize(using=CustomDeserializer.class)
public class UnsignedNumericClass extends Number
I think a custom deserializer for BigInteger
is predefined in Jackson so this issue does not appear for that class. 我认为在Jackson中预定义了
BigInteger
的自定义解串器,因此该类不会出现此问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.