即使存在默认构造函数,也无法从 Object 值反序列化(没有基于委托或基于属性的 Creator)

Posted

技术标签:

【中文标题】即使存在默认构造函数,也无法从 Object 值反序列化(没有基于委托或基于属性的 Creator)【英文标题】:cannot deserialize from Object value (no delegate- or property-based Creator) even with default constructor present 【发布时间】:2019-03-13 12:12:30 【问题描述】:

我有一个看起来像这样的课程

class MyClass 
    private byte[] payload;

    public MyClass()

    @JsonCreator
    public MyClass(@JsonProperty("payload") final byte[] payload) 
        this.payload = payload;
    

    public byte[] getPayload() 
        return this.payload;
    


我正在使用 Jackson 进行序列化然后反序列化。序列化工作正常,但在反序列化期间,我收到此错误消息 -

Cannot construct instance of `mypackage.MyClass` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

我在网上阅读了有关此问题的信息,并遇到了一些建议使用默认构造函数或带有 @JsonCreator 注释的构造函数的文本。我尝试同时添加两者,但仍然出现异常。我在这里错过了什么?

【问题讨论】:

我用 Jackson 2.9.7 测试了 like this 并且反序列化工作正常。 【参考方案1】:

编辑:

我刚刚找到了一个更好的解决方案,将ParanamerModule 添加到ObjectMapper

mapper.registerModule(new ParanamerModule());

马文:

<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-paranamer</artifactId>
    <version>$jackson.version</version>
</dependency>

相对于ParameterNamesModule 的优势似乎是类不需要使用-parameters 参数进行编译。

结束编辑


在 Jackson 2.9.9 中,我尝试反序列化这个简单的 POJO 并遇到相同的异常,添加默认构造函数解决了问题:

POJO:

public class Operator 

    private String operator;

    public Operator(String operator) 
        this.operator = operator;
    

    public String getOperator() 
        return operator;
    

ObjectMapper 和序列化/反序列化:

ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE);
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
mapper.setVisibility(PropertyAccessor.CREATOR, Visibility.ANY);

String value = mapper.writeValueAsString(new Operator("test"));
Operator result = mapper.readValue(value, Operator.class);

JSON:

"operator":"test"

例外:

com.fasterxml.jackson.databind.exc.MismatchedInputException: 
Cannot construct instance of `...Operator` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)""operator":"test""; line: 1, column: 2]

解决方案(带有默认构造函数的POJO):

public class Operator 

    private String operator;

    private Operator() 
    

    public Operator(String operator) 
        this();
        this.operator = operator;
    

    public String getOperator() 
        return operator;
    

【讨论】:

添加paranamer模块并不能解决jackson由于缺少空构造函数而无法创建对象的问题。使用参数 2.12.2 测试 你的解决方案是禁止最终属性,因为杰克逊。敦促。【参考方案2】:

我观察到了同样的问题。我的问题是由我使用 wrong JsonCreator 类型引起的。我错误地使用了 org.codehaus.jackson.annotate.JsonCreator,但应该改用 com.fasterxml.jackson.annotation.JsonCreator

【讨论】:

【参考方案3】:

在你的子类对象中添加默认构造函数:

public NameOfClass() 
    super();

【讨论】:

@Data(添加了@RequiredArgsConstructor)确实是不够的。我必须使属性非final 并添加@NoArgsConstructor【参考方案4】:

我遇到了这种序列化和反序列化kotlin data classes。我所要做的就是为我的属性添加默认值,然后读取有效的值。

data class DataClass(
  val key: String = "",    //  adding these default 
  val value: String = ""   //  values worked
)

没有= "",我会得到错误:

Cannot construct instance of `com.xxx.DataClass` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

【讨论】:

【参考方案5】:

我遇到了同样的问题,上述解决方案都没有帮助。在发现调试版本运行良好之后,R8 应该受到指责,因为它剥离了 Jackson 在发布版本中需要的一些代码。将@JsonAutoDetect 添加到所有自定义类依赖项中解决了该错误。

@JsonAutoDetect
data class Car(
    val name: String // annotation not needed
    val engine: Engine // annotation needed
)
// @JsonAutoDetect is needed here
data class Engine(
    val name: String
)

【讨论】:

【参考方案6】:

我收到了这个错误,我尝试了https://newbedev.com/no-creators-like-default-construct-exist-cannot-deserialize-from-object-value-no-delegate-or-property-based-creator

基本添加

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)

装饰器,它对我有用。

【讨论】:

【参考方案7】:

我也面临同样的问题,在我的情况下,我在声明中使用 Java 中的 REST API...但是经过多次尝试后,我发现我需要添加默认构造函数,因为我已经声明了构造函数字段..

public NameofClass() 
        super();
        // TODO Auto-generated constructor stub
    

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。 请通过清除代码 sn-ps 即兴发挥你的 cmets

以上是关于即使存在默认构造函数,也无法从 Object 值反序列化(没有基于委托或基于属性的 Creator)的主要内容,如果未能解决你的问题,请参考以下文章

没有从字符串值反序列化的字符串参数构造函数/工厂方法('2018-12-14')

没有像默认构造一样的创建者):不能从对象值反序列化(没有基于委托或属性的创建者

反序列化错误 : 不能构造Dto的实例(尽管至少有一个Creator存在):不能从对象值反序列化。

Spring Boot:没有从字符串值反序列化的字符串参数构造函数/工厂方法

Jackson MismatchedInputException(没有从字符串值反序列化的字符串参数构造函数/工厂方法)

objectmapper.readValue() 失败并出现错误“没有从字符串值反序列化的字符串参数构造函数/工厂方法”