针对@RequestBody搭配@Data可能会遇到的大坑,我可以提供以下攻略:
针对@RequestBody搭配@Data可能会遇到的大坑,我可以提供以下攻略:
问题描述
使用Spring Boot开发Web应用时,我们经常会使用注解@RequestBody来接收前端传过来的Json格式请求数据,而为了简化我们的代码,我们可以使用Lombok注解@Data来自动生成getter、setter、toString、equals和hashCode等方法。但是在使用这两个注解的时候,可能会遇到如下问题:
- 使用@Data注解的Java Bean反序列化@RequestBody时,如果Json字符串中的字段名与Java Bean中的字段名不一样,将无法成功反序列化。
- 如果我们的请求数据中包含了枚举字段,并且枚举类中实现了getDisplay()或者getDesc()方法来返回字段对应的描述值,此时我们需要自定义反序列化器,否则将无法成功反序列化。
解决方案
解决问题1:使用@JsonProperty注解
为了解决第一个问题,我们可以在Java Bean中使用@JsonProperty注解,将Json中的字段名和Java Bean中的字段名进行映射。
例如,我在Java Bean对象中定义了如下字段:
@Data
public class UserVO {
@JsonProperty("id")
private Long userId;
}
当我们接收到如下Json字符串时:
{
"id": 123456,
"name": "小明"
}
使用如下代码可以成功反序列化:
@PostMapping("/user")
public void addUser(@RequestBody UserVO userVO) {
System.out.println(userVO.getUserId());
System.out.println(userVO.getName());
}
解决问题2:自定义反序列化器
为了解决第二个问题,我们可以自定义反序列化器来处理枚举类型的字段。
假设我们有一个OrderVO对象,含有一个Status枚举类型的字段:
@Data
public class OrderVO {
private Long id;
private String orderNo;
private Status status;
}
Status枚举中定义了getDisplay()方法来返回枚举描述值:
@Getter
@AllArgsConstructor
public enum Status {
CREATED("created", "已创建"),
PAID("paid", "已支付"),
SHIPPED("shipped", "已发货"),
RECEIVED("received", "已收货");
private String code;
private String display;
public static Status getByCode(String code) {
for (Status status : Status.values()) {
if (status.getCode().equals(code)) {
return status;
}
}
throw new IllegalArgumentException("invalid Status code: " + code);
}
public String getDisplay() {
return display;
}
}
为了让Spring Boot能够正确反序列化Status字段,我们需要自定义反序列化器:
@Component
public class StatusDeserializer extends JsonDeserializer<Status> {
@Override
public Status deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
String code = jsonParser.getText();
return Status.getByCode(code);
}
}
然后在OrderVO类中使用@JsonDeserialize注解和我们自定义的反序列化器:
@Data
public class OrderVO {
private Long id;
private String orderNo;
@JsonDeserialize(using = StatusDeserializer.class)
private Status status;
}
这样,在我们接收到如下Json字符串时:
{
"id": 123456,
"orderNo": "202201010001",
"status": "paid"
}
使用如下代码可以成功反序列化:
@PostMapping("/order")
public void addOrder(@RequestBody OrderVO orderVO) {
System.out.println(orderVO.getStatus().getDisplay());
}
以上就是解决@RequestBody搭配@Data的大坑的完整攻略。
本文标题为:解决@RequestBody搭配@Data的大坑
基础教程推荐
- SpringBoot详细讲解yaml配置文件的用法 2023-02-05
- Java Web监听器Listener接口原理及用法实例 2024-02-29
- Java去掉小数点后面无效0的方案与建议 2023-02-19
- Java Socket 编程详解 2023-07-15
- PHP中auto_prepend_file与auto_append_file用法实例分析 2023-12-15
- 将BigDecimal转成字符串为科学计数法的踩坑记录 2023-01-17
- MybatisPlus查询条件为空字符串或null问题及解决 2023-02-05
- java中如何截取字符串最后一位 2023-02-19
- SpringBatch从入门到精通之StepScope作用域和用法详解 2022-11-29
- Java操作MinIO存储服务的API示例 2023-10-08