我需要在其树中包含AtomicLong
的{{3}} Java类。
我初始化 Jackson 2.9.2 的ObjectMapper如下
private final static ObjectMapper objectMapper = new ObjectMapper()///
.findAndRegisterModules()//
.enableDefaultTyping(DefaultTyping.NON_FINAL, As.WRAPPER_OBJECT)//
.setDefaultPrettyPrinter(new MinimalPrettyPrinter())//
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)//
.disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES)//
.disable(SerializationFeature.INDENT_OUTPUT)//
.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
然后我将我的类序列化为JSON,为此我显示了罪魁祸首片段
"progress":{"com.acme.SimpleProgressObject":{"current":0,"total":null,"status":null,"error":null,"innerProgress":null}}
注意current
等于plain 0. Class由
public class SimpleProgressObject implements AsyncProgress, AsyncProgressSupplier, Serializable
{
private final AtomicLong current = new AtomicLong(0);
private AtomicLong total;
private String status;
private Throwable error;
private SimpleProgressObject innerProgress;
}
当我从容器中反序列化这些东西时,我收到以下错误
com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (VALUE_NUMBER_INT), expected START_OBJECT: need JSON Object to contain As.WRAPPER_OBJECT type information for class java.util.concurrent.atomic.AtomicLong
at [Source: [truncated]; line: 1, column: 145] (through reference chain: ProcessExecutionContext["progress"]->SimpleProgressObject["current"])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:1498)
at com.fasterxml.jackson.databind.DeserializationContext.reportWrongTokenException(DeserializationContext.java:1273)
at com.fasterxml.jackson.databind.jsontype.impl.AsWrapperTypeDeserializer._deserialize(AsWrapperTypeDeserializer.java:100)
at com.fasterxml.jackson.databind.jsontype.impl.AsWrapperTypeDeserializer.deserializeTypedFromObject(AsWrapperTypeDeserializer.java:52)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1156)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:287)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.jsontype.impl.AsWrapperTypeDeserializer._deserialize(AsWrapperTypeDeserializer.java:121)
at com.fasterxml.jackson.databind.jsontype.impl.AsWrapperTypeDeserializer.deserializeTypedFromObject(AsWrapperTypeDeserializer.java:52)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1156)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:287)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.jsontype.impl.AsWrapperTypeDeserializer._deserialize(AsWrapperTypeDeserializer.java:121)
at com.fasterxml.jackson.databind.jsontype.impl.AsWrapperTypeDeserializer.deserializeTypedFromObject(AsWrapperTypeDeserializer.java:52)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1156)
at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:68)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
我认为正确的JSON可能已经(美化)
{
"progress":{
"com.acmeSimpleProgressObject":{
"current":{
"java.util.concurrent.AtomicLong":0
},
"total":null,
"status":null,
"error":null,
"innerProgress":null
}
}
}
问题是:我的代码是错误的还是杰克逊本身的问题?我没有怀疑在Github上打开一个问题
编辑1:改变.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY)//
答案 0 :(得分:0)
不幸的是我没有发布getter / setter,这有助于理解罪魁祸首
@Override
public Long getCurrent()
{
if (current == null)
return null;
return current.longValue();
}
@Override
public Long getTotal()
{
if (total == null)
return null;
return total.longValue();
}
@Override
public void setTotal(Long total)
{
if (total == null)
this.total = null;
else
this.total = new AtomicLong(total);
}
@Override
public String getStatus()
{
return status;
}
@Override
public void setStatus(String status)
{
this.status = status;
}
@Override
public Throwable getError()
{
return error;
}
由于我有current
的getter返回Long
,因此Jackson使用它将其序列化为基本类型,而不包装。它实际上不是一个getter,而是一种遵守接口契约的实用方法。
然而,当反序列化时,杰克逊能够通过反射设置最终字段,但在有效负载中找到原始值。后者是正确的行为,但是由我的非规范吸气剂引起。
我的解决方案是添加一个接受@JsonSetter("current") Long current
我希望立即关闭这个问题,因为它与我的案例非常具体,但在找到原因的所有努力之后,我要求社群决定这个问题的生命。