小编典典

使用新的Record类时无法反序列化

spring-boot

我试图查看是否可以用Java 14中的新Record类替换现有的Pojos。但是无法这样做。出现以下错误:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造的实例com.a.a.Post(不存在创建者,如默认构造一样):无法从对象值反序列化(没有基于委托或基于属性的创建者)

我得到的错误是说记录没有构造函数,但是从我看来,记录类在后台处理它,并且相关的吸气剂也在后台设置(不是完全的吸气剂,而是id()title()等等)上没有get前缀)。是因为Spring尚未采用最新的Java
14记录吗?请指教。谢谢。

我正在Spring Boot版本2.2.6中使用Java 14。

以下使用普通的POJO进行工作。

邮政课

public class PostClass {
    private int userId;
    private int id;
    private String title;
    private String body;

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }
}

调用rest服务的方法现在可以正常工作,因为我正在使用上述POJO。

public PostClass[] getPosts() throws URISyntaxException {
    String url = "https://jsonplaceholder.typicode.com/posts";
    return template.getForEntity(new URI(url), PostClass[].class).getBody();
}

但是,如果我改用跟随我正在使用记录的位置,则会收到上述错误。

新记录类。

public record Post(int userId, int id, String title, String body) {
}

更改方法以使用记录,但失败。

public Post[] getPosts() throws URISyntaxException {
    String url = "https://jsonplaceholder.typicode.com/posts";
    return template.getForEntity(new URI(url), Post[].class).getBody();
}

编辑:

尝试向记录Post和相同错误中添加如下构造函数:

public record Post(int userId, int id, String title, String body) {
    public Post {
    }
}

要么

public record Post(int userId, int id, String title, String body) {
    public Post(int userId, int id, String title, String body) {
        this.userId = userId;
        this.id = id;
        this.title = title;
        this.body = body;
    }
}

阅读 472

收藏
2020-05-30

共1个答案

小编典典

编译器为Record生成构造函数和其他访问器方法。

就你而言

  public final class Post extends java.lang.Record {  
  public Post(int, int java.lang.String, java.lang.String);
  public java.lang.String toString();
  public final int hashCode();
  public final boolean equals(java.lang.Object);
  public int userId();
  public int id();
  public java.lang.String title();
  public java.lang.String body();
}

在这里您可以看到Jackson并不需要默认的构造函数。您使用的构造函数是紧凑的构造函数,

public Post {
 }

您可以将默认/无参数构造函数定义为

public record Post(int userId, int id, String title, String body) {
    public Post() {
        this(0,0, null, null);
    }
}

但是杰克逊使用Getter和Setters来设置值。简而言之,您不能使用Record映射响应。

2020-05-30