You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中如何正确定义指定JSON请求体对应的Java类?

Spring Boot中JSON请求体对应Java类的正确定义方案

针对你给出的JSON请求体,当前编写的Film、Genre、Rating类存在mpa和genres字段的序列化/反序列化问题,核心原因是嵌套类缺少Jackson可识别的构造逻辑,同时Film类还存在字段缺失、反序列化适配问题,以下是具体修复方案:

1. 修复Genre和Rating类的序列化问题

Genre和Rating类的id是final字段,@Data注解仅生成带参构造器,Jackson默认无法自动识别该构造器完成反序列化,需要显式指定构造器并绑定JSON字段映射:

修改后的Genre类:

@Data
public class Genre {
    @Positive
    private final long id;

    @JsonCreator
    public Genre(@JsonProperty("id") long id) {
        this.id = id;
    }
}

修改后的Rating类:

@Data
public class Rating {
    @Positive
    private final long id;

    @JsonCreator
    public Rating(@JsonProperty("id") long id) {
        this.id = id;
    }
}
  • @JsonCreator告诉Jackson使用该构造器创建实例
  • @JsonProperty("id")指定构造器参数对应JSON中的id字段,确保映射准确

2. 调整Film类的问题

补充缺失字段

JSON请求体中的rate字段未在Film类中定义,需要添加对应字段:

@Positive
private final int rate;

适配Jackson反序列化

你的Film类使用了Builder模式和final字段,默认Jackson无法直接通过Builder完成反序列化,可通过两种方式解决:

方式一:使用@Jacksonized注解(推荐)

引入jackson-module-parameter-names依赖(Spring Boot 2.x+默认包含),配合@Builder添加@Jacksonized注解,让Jackson支持Builder模式的反序列化:

@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@Builder
@Jacksonized // 启用Jackson对Builder的支持
public class Film extends Entity implements Comparable<Film> {

    @NotBlank
    private final String name;
    @NonNull
    @Size(max = 200, message = "Description name longer than 200 symbols")
    private final String description;
    @NonNull
    @Past
    @JsonFormat(pattern = "yyyy-MM-dd", shape = JsonFormat.Shape.STRING)
    private final LocalDate releaseDate;

    @NonNull
    @Positive
    private final int duration;

    @Positive
    private final int rate;

    private final Rating mpa;

    private final List<Genre> genres;

    @Setter(value = AccessLevel.PRIVATE)
    private Set<Long> likes;

    // 保留继承自Entity的id构造逻辑
    public Film(long id, String name, @NonNull String description, @NonNull LocalDate releaseDate, @NonNull int duration, int rate, List<Genre> genres, Rating mpa, Set<Long> likes) {
        super(id);
        this.name = name;
        this.description = description;
        this.releaseDate = releaseDate;
        this.duration = duration;
        this.rate = rate;
        this.genres = genres;
        this.mpa = mpa;
        this.likes = likes;
    }

    @Override
    public int compareTo(Film o) {
        // 实现你的自定义比较逻辑
        return 0;
    }
}

方式二:给构造器添加字段映射注解

如果不想依赖额外模块,可给Film的全参构造器添加@JsonCreator和@JsonProperty注解,明确参数与JSON字段的对应关系:

@JsonCreator
public Film(@JsonProperty("id") long id,
            @JsonProperty("name") String name,
            @JsonProperty("description") @NonNull String description,
            @JsonProperty("releaseDate") @NonNull LocalDate releaseDate,
            @JsonProperty("duration") @NonNull int duration,
            @JsonProperty("rate") int rate,
            @JsonProperty("genres") List<Genre> genres,
            @JsonProperty("mpa") Rating mpa,
            @JsonProperty("likes") Set<Long> likes) {
    super(id);
    this.name = name;
    this.description = description;
    this.releaseDate = releaseDate;
    this.duration = duration;
    this.rate = rate;
    this.genres = genres;
    this.mpa = mpa;
    this.likes = likes;
}

3. 额外注意事项

  • Spring Boot Starter Web默认包含jackson-datatype-jsr310依赖,可正常支持LocalDate的序列化/反序列化,你已配置的@JsonFormat注解无需调整。
  • 如果业务上要求mpa和genres字段必填,可给这两个字段添加@NonNull注解,配合校验框架实现参数校验。

内容的提问来源于stack exchange,提问作者Zainn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 21:36:26