使用 writeValueAsString 序列化对象后,Jackson 反序列化失败

问题描述 投票:0回答:5

使用 com.fasterxml.jackson.databind.ObjectMapper 类(com.fasterxml.jackson.core:jackson-databind:2.9.5) 我正在尝试反序列化以下类的对象:

class MyClass {

    String name;

    MyClass(String name) {
        this.name = name;
    }
}

我当前正在执行的代码如下:

    MyClass myClass = new MyClass("test");
    objectMapper.registerModule(new ParameterNamesModule())
        .registerModule(new Jdk8Module())
        .registerModule(new JavaTimeModule())
        .configure(FAIL_ON_UNKNOWN_PROPERTIES, false)
        .setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

    String text = objectMapper.writeValueAsString(myClass);
    objectMapper.readValue(text, MyClass.class);

最后一行失败并抛出异常:

com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造

com.pckge.MyClass
的实例(尽管至少存在一个创建者):无法从对象值反序列化(没有基于委托或属性的创建者) 在 [来源:(String)"{"name":"test"}";行:1,列:2]

我的目标是配置对象映射器,以便成功反序列化对象,而无需在 MyClass 的构造函数上使用 JsonCreator 或 JsonProperties 等注释:

  • 这可行吗?
  • 我缺少哪个配置?

非常感谢!

编辑1:@Dean 的回复解决了问题。但是我也想避免使用默认构造函数。

java spring-boot serialization jackson deserialization
5个回答
24
投票

在没有默认构造函数的情况下解决此问题的正确方法是将 JsonCreator 和 JsonProperty 注释添加到类构造函数中。

class MyClass {

    String name;

    @JsonCreator
    MyClass(@JsonProperty("name") String name) {
        this.name = name;
    }
    ...
}

12
投票

Jackson 使用 Getter 和 Setters 来设置值。所以你需要修改你的类:

class MyClass {

    String name;

    MyClass(String name) {
      this.name = name;
   }

   MyClass(){}

   public void setName(String name) {
     this.name = name;
   }

  public String getName(String name) {
     return this.name;
  }
}

7
投票

如果您使用的是 lombok,请删除该类的 @Builder 注释,这是我的问题


2
投票

我的方法是从类中删除@Builder(Lombok)注释并添加@AllArgsConstructor和@NoArgsConstructor注释,它起作用了


0
投票

我删除了@Builder(Lombok),它起作用了,因为@Builder创建了一个私有构造函数。

© www.soinside.com 2019 - 2024. All rights reserved.