2016-11-29 122 views
0

我想用Jackson来序列化和反序列化一个自定义的数字类,它扩展了java.lang.Number。下面是该课程的准系统实施,没有扩展NumberJackson的序列化和java.lang.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

davidxxx确实是正确的,当数序列大于Long.MAX_VALUE是反序列化只是失败。这个问题比这个要深一点。

UnsignedNumericClass未延伸Number时,杰克逊将其视为普通对象,并通过getter,setters和默认构造函数UnsignedNumericClass()进行序列化/反序列化。

一旦UnsignedNumericClass延伸Number,杰克逊更改为序列化/反序列化通过toString()和字符串参数构造函数UnsignedNumericClass(String data)。请注意,如果String参数构造函数不存在,则会引发异常。

我遇到了问题,因为我正在实现一个无符号的64位数字。由于该数字未经签名,因此我的toString()实现将打印private long data字段的未签名解释。

当对数字类型进行反序列化时,Jackson执行检查以确保它是有效的数字。也就是说,它检查JSON文档中给出的数字是否小于Long.MAX_VALUE。如果不是这种情况,它依赖于一个自定义的反序列化器,而不是仅仅使用我可以处理数字的String参数构造器。由于没有指定自定义的反序列化器,它会抛出“不合适的创建者方法”异常。因此,解决方法是定义使用字符串参数的构造一个简单的自定义解串器:

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 

我想自定义在Jackson中预定义了BigInteger的解串器,所以该问题不会出现在该类中。