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
相关产品推荐
相关产品推荐

