Jackson更新到2.8.1后尝试使用所有参数构造函数

时间:2016-09-09 18:42:41

标签: spring-boot jackson

我刚刚将弹簧启动从1.3.2更新到1.4,因此也将jackson从2.6.5更新到2.8.1。

在代码中没有其他变化时,jackson现在尝试使用all-args-constructor(AnnotatedConstructor.java:124)而不是普通的no-args-constructor(AnnotatedConstructor.java:120)来创建我的模型类的实例。

由于jackson以错误的顺序使用构造函数(为Long设置String),因此会导致异常:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.example.PoJO, problem: argument type mismatch
at [Source: java.io.PushbackInputStream@52de93f1; line: 1, column: 1138]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:268)
at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:1405)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.wrapAsJsonMappingException(StdValueInstantiator.java:468)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.rewrapCtorProblem(StdValueInstantiator.java:487)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromObjectWith(StdValueInstantiator.java:276)
at com.fasterxml.jackson.databind.deser.ValueInstantiator.createFromObjectWith(ValueInstantiator.java:224)
at com.fasterxml.jackson.databind.deser.impl.PropertyBasedCreator.build(PropertyBasedCreator.java:135)
at com.fasterxml.jackson.databind.deser.impl.ExternalTypeHandler.complete(ExternalTypeHandler.java:225)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeUsingPropertyBasedWithExternalTypeId(BeanDeserializer.java:937)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeWithExternalTypeId(BeanDeserializer.java:792)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:312)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3789)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2913)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:225)
... 52 common frames omitted
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at com.fasterxml.jackson.databind.introspect.AnnotatedConstructor.call(AnnotatedConstructor.java:124)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromObjectWith(StdValueInstantiator.java:274)
... 62 common frames omitted

由于我没有对代码进行任何更改,因此我不知道从哪里开始调试。我确认将jackson修复回2.6.5可以解决这个问题。

为什么jackson会尝试使用all-args-constructor,有没有办法强制使用no-args-constructor?

2 个答案:

答案 0 :(得分:2)

我不得不使用这个答案:how to specify jackson to only use fields - preferably globally

感谢@StaxMan的评论:

  

你是否有机会使用龙目岛?   如果是这样,默认情况下会增加@ConstructorProperties,杰克逊会将其解释为@JsonCreator

在要反序列化的对象上,删除自动JsonCreator自动检测:

@Value
@AllArgsConstructor
// Add a private default constructor used through reflection
@NoArgsConstructor(access = AccessLevel.PRIVATE, force = true)
// Deactivate JsonCreator auto detection
@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, creatorVisibility = Visibility.NONE)
public class ValueObject {

    @NotEmpty
    private String x;
}

龙目岛的@AllArgsConstructor不允许您再次覆盖suppressConstructorProperties

lombok.config文件中,添加:

lombok.anyConstructor.suppressConstructorProperties=true

答案 1 :(得分:0)

查看Jackson注释,我猜你可以明确地使用no args构造函数:

public class YourPojo {
   @JsonCreator
   public YourPojo(){}
}