目录
一、引入
一般在写Springboot项目时,@RequestBody 这个注解会经常在后端向前端返回JSON数据或者后端多模块间的通信这些场景。但这个注解具体什么时候用,什么时候不用呢?
下面将借助实体类Person来探讨@RequestBody 注解的使用时机。
@Data
public class Person {
private Integer id;
private String name;
private Integer age;
}
二、常见的发送数据方法
根据请求头和请求体的有无、请求所携带数据的类型,将发送数据的方式简单分为以下几类:
2.1有请求头,但没有请求体【GET】
(1)前端发送
参数直接在URL中携带,例如:
http://localhost:8080/url?id=1&name=jack&age=20
(2)后端封装
不使用@RequestBody
@GetMapping("/url")
public Person saveUrl(Person person){
return person;
}
2.2有请求头,请求体的数据类型为表单【POST】
(1)前端发送
请求头:
Content-Type:multipart/form-data
请求体如下:
Key | Value |
id | 1 |
name | jack |
age | 20 |
(2)后端封装
不使用@RequestBody
@PostMapping("/form")
public Person saveForm(Person person){
return person;
}
2.3有请求头,请求体数据类型为JSON【POST】
(1)前端发送
请求头:
Content-Type:application/json
请求体:
{
"id":1,
"name":"jack",
"age":20
}
(2)后端封装
这里需要用到@RequestBody ,否则无法将json数据封装为Person对象
@PostMapping("/json")
public Person saveJson(@RequestBody Person person){
return person;
}
2.4后端两模块间通信
最经典的就是生产者模块与消费者模块间的通信,可以用下面的图来表示:
如果使用RestTemplate进行组件通信的话,当消费者传递给生产者的数据是一个对象类型时,生产者在接收该数据时需要用到@RequestBody 注解,否则接收到的数据将为null。
下面是一个使用例子:
消费者
public static final String MEMBER_SERVICE_PROVIDER_URL =
"http://localhost:10000";
@Resource
private RestTemplate restTemplate;
@PostMapping("/member/consumer/save")
public Result<Member> save(Member member){
log.info("消费者接收的数据={}",member);
return restTemplate.postForObject(MEMBER_SERVICE_PROVIDER_URL + "/member/save", member, Result.class);
}
生产者
@Resource
private MemberService memberService;
@PostMapping("/member/save")
public Result save(@RequestBody Member member){
log.info("生产者接收到的数据={}",member);
int affected = memberService.save(member);
if(affected > 0){
return Result.success("添加会员成功",affected);
}else {
return Result.error("401","添加会员失败...");
}
}
三、总结
1. 对于传统的数据请求方式(表单、URL参数),Spring可以做到自动封装,不用加@RequestBody;(如果加了的话,请求时会报415的错)
2.对于携带JSON数据的这类请求,需要用@RequestBody 注解对后端方法的入参加以修饰,从而达到自动封装成JavaBean的效果;
3.当使用RestTemlate的方法发送数据时,如果传递的数据类型为对象,那么在接收时需要使用@RequestBody