How do correctly use Jackson Mixin annotation to instantiate a third party class?

匿名 (未验证) 提交于 2019-12-03 01:00:01

问题:

I have a third party library class (from Apache Axis) that I want to serialize by 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);         }     } } 

I have my entity class containing a NonNegativeInteger field that I want to serialize by JSON:

public class TestEntity {      private NonNegativeInteger number;      public NonNegativeInteger getNumber() {         return number;     }      public void setNumber(NonNegativeInteger number) {         this.number = number;     } } 

When I serialize the above object by Jackson JSON, I got the following error:

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

Then I looked at the POST request entity, it is actually {"number" : 10} as serialized by Jackson. But since NonNegativeInteger doesn't have a constructor taking a single-int, Jackson can't instantiate a NonNegativeInteger object. So I followed someone's suggestions to add a Mixin class for NonNegativeInteger so that it will have a constructor with int as arg:

public abstract class NonNegativeIntegerMixin extends NonNegativeInteger {      @JsonCreator     public NonNegativeIntegerMixin(int val) {         super(String.valueOf(val));     } } 

Then I registered it in my JSON configuration class:

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

But it doesn't help, it still reported the same error. I tried manually writing the JSON request body to be {"number": "10"} then it worked well. But my client side used Jackson to serialize NonNegativeInteger. Jackson automatically converts to {"number": 10} without quotes. How can I fix this error?

Edit:

The NonNegativeInteger class doesn't have any class field (except a constant zero field). The number key is from my TestEntity class. So I even if I add @JsonProperty annotation in my NonNegativeIntegerMixin mixin class, Jackson JSON will not instantiate a NonNegativeInteger with an int type arg. Therefore, I still got the same error.

回答1:

Your mix-in annotation seems correct to me. So this could be a bug; so maybe file bug at:

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

One possible reason for problems is that class is extending BigInteger, which has existing deserializer. This could result in annotations being ignored, wrt how instances are deserialized.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!