问题
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.
来源:https://stackoverflow.com/questions/28857897/how-do-correctly-use-jackson-mixin-annotation-to-instantiate-a-third-party-class