【问题标题】:How do correctly use Jackson Mixin annotation to instantiate a third party class?如何正确使用 Jackson Mixin 注解来实例化第三方类?
【发布时间】:2015-05-05 15:28:03
【问题描述】:

我有一个第三方库类(来自 Apache Axis),我想通过 Jackson JSON 进行序列化:

public class NonNegativeInteger extends BigInteger {

    public NonNegativeInteger(byte[] val) {
        super(val);
        checkValidity();
    } // ctor

    public NonNegativeInteger(int signum, byte[] magnitude) {
        super(signum, magnitude);
        checkValidity();
    } // ctor

    public NonNegativeInteger(int bitLength, int certainty, Random rnd) {
        super(bitLength, certainty, rnd);
        checkValidity();
    } // ctor

    public NonNegativeInteger(int numBits, Random rnd) {
        super(numBits, rnd);
        checkValidity();
    } // ctor

    public NonNegativeInteger(String val) {
        super(val);
        checkValidity();
    }

    public NonNegativeInteger(String val, int radix) {
        super(val, radix);
        checkValidity();
    } // ctor

    /**
     * validate the value against the xsd definition
     */
    private BigInteger zero = new BigInteger("0");
    private void checkValidity() {
        if (compareTo(zero) < 0) {
            throw new NumberFormatException(
                    Messages.getMessage("badNonNegInt00")
                    + ":  " + this);
        }
    } // checkValidity

    /**
     * Work-around for http://developer.java.sun.com/developer/bugParade/bugs/4378370.html
     * @return BigIntegerRep
     * @throws ObjectStreamException
     */ 
    public Object writeReplace() throws ObjectStreamException {
        return new BigIntegerRep(toByteArray());
    }

    protected static class BigIntegerRep implements java.io.Serializable {
        private byte[] array;
        protected BigIntegerRep(byte[] array) {
            this.array = array;
        }
        protected Object readResolve() throws java.io.ObjectStreamException {
            return new NonNegativeInteger(array);
        }
    }
}

我的实体类包含一个我想通过 JSON 序列化的 NonNegativeInteger 字段:

public class TestEntity {

    private NonNegativeInteger number;

    public NonNegativeInteger getNumber() {
        return number;
    }

    public void setNumber(NonNegativeInteger number) {
        this.number = number;
    }
}

当我通过 Jackson JSON 序列化上述对象时,出现以下错误:

Can not instantiate value of type [simple type, class org.apache.axis.types.NonNegativeInteger] from Integral number; no single-int-arg constructor/factory method

然后我查看了POST请求实体,它实际上是Jackson序列化的{"number" : 10}。但由于NonNegativeInteger 没有采用单整数的构造函数,杰克逊无法实例化NonNegativeInteger 对象。所以我按照某人的建议为 NonNegativeInteger 添加了一个 Mixin 类,这样它就有一个以 int 为 arg 的构造函数:

public abstract class NonNegativeIntegerMixin extends NonNegativeInteger {

    @JsonCreator
    public NonNegativeIntegerMixin(int val) {
        super(String.valueOf(val));
    }
}

然后我在我的 JSON 配置类中注册了它:

 objectMapper.addMixInAnnotations(NonNegativeInteger.class, NonNegativeIntegerMixin.class);

但是没有用,还是报同样的错误。我尝试手动将 JSON 请求正文编写为 {"number": "10"},然后效果很好。但是我的客户端使用 Jackson 来序列化NonNegativeInteger。 Jackson 自动转换为{"number": 10},不带引号。我该如何解决这个错误?

编辑:

NonNegativeInteger 类没有任何类字段(常量zero 字段除外)。 number 密钥来自我的 TestEntity 类。因此,即使我在 NonNegativeIntegerMixin mixin 类中添加 @JsonProperty 注释,Jackson JSON 也不会实例化带有 int 类型 arg 的 NonNegativeInteger。因此,我仍然遇到同样的错误。

【问题讨论】:

    标签: java json serialization jackson mixins


    【解决方案1】:

    您的混合注释对我来说似乎是正确的。所以这可能是一个错误;所以可能会在以下位置提交错误:

    https://github.com/FasterXML/jackson-databind/issues/

    问题的一个可能原因是该类正在扩展BigInteger,它具有现有的反序列化器。这可能会导致注释被忽略,不管实例是如何反序列化的。

    【讨论】:

    • 谢谢。我也这么认为。 Apache Axis 类NonNegativeIntegerBigInteger 的派生类。如果我在 TestEntity 类中使用 BigInteger,则不会出现错误。 Jackson 可以正确地 se/反序列化 {"number":10}{"number":"10"}。但是如果我在我的TestEntity 类中使用NonNegativeInteger 作为一个字段,Jackson 总是将其序列化/反序列化为{"number":10},这会导致问题,因为NonNegativeInteger 没有int-arg 构造函数,而我的 Mixin 类是不是杰克逊挑选的。
    • 正确:最有可能的处理只需要首先检查创建者注释,然后使用它。并不是所有的默认反序列化器都考虑到可定制性。
    猜你喜欢
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多