我正在尝试使用Jackson序列化和反序列化扩展java.lang.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;}
}
这对杰克逊来说非常好,但是第二次我把课程改为
public class UnsignedNumericClass extends Number
杰克逊没有反序列化声称“没有找到合适的创建者方法从数值反序列化(14169630718280903901)”。此外,它有时只会失败。
有谁知道为什么会这样,或者如何让杰克逊成功反序列化为扩展java.lang.Number
的类的实例?
答案 0 :(得分:0)
davidxxx确实是正确的,当序列化数量大于Long.MAX_VALUE
时,反序列化才会失败。问题比这更深入。
当UnsignedNumericClass
未扩展Number
时,杰克逊将其视为普通对象,并通过getter,setter和默认构造函数UnsignedNumericClass()
进行序列化/反序列化。
一旦UnsignedNumericClass
扩展Number
,杰克逊就会通过toString()
和字符串参数构造函数UnsignedNumericClass(String data)
更改为序列化/反序列化。请注意,如果String-argument构造函数不存在,则抛出异常。
我遇到了质疑问题,因为我正在实现一个无符号的64位数字。由于该数字是无符号的,因此我的toString()
实现会打印private long data
字段的无符号解释。
在反序列化数字类型时,Jackson会执行检查以确保它是有效数字。也就是说,它会检查JSON文档中给出的数字是否小于Long.MAX_VALUE
。如果不是这种情况,它依赖于自定义反序列化器,而不是仅仅使用我的String-argument构造函数,它可以很好地处理数字。由于未指定自定义反序列化器,因此会抛出“无合适的创建者方法”异常。因此,解决方案是定义一个使用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());
}
然后我们通过@JsonDeserialize()
注释指定杰克逊使用这个反序列化器:
@JsonDeserialize(using=CustomDeserializer.class)
public class UnsignedNumericClass extends Number
我认为BigInteger
的自定义反序列化程序是在Jackson中预定义的,所以这个问题不适用于该类。