1.@RequestBody和@RequestParam的区别

post请求

不用@RequestBody注解

@RequestMapping("/post/test")
@PostMapping
public String testPost(StudentDTO dto) {
	return dto.toString();
}

如果后台接口是这样写的话,前端请求接口用form-datax-www-form-urlencodedapplication/json这三种方式发送请求,后端接口都不能接收到参数的值。

用@RequestBody注解

@RequestMapping("/post/test1")
@PostMapping
public String testPost1(@RequestBody StudentDTO dto) {
    return dto.toString();
}

如果后台接口是这样写的话:

前端如果用form-data格式发送请求
  1. 页面会得到错误:
{"timestamp":1604191503418,"status":400,"error":"Bad Request","message":"JSON parse error: Unexpected character ('-' (code 45)) in numeric value: expected digit (0-9) to follow minus sign, for valid numeric value; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('-' (code 45)) in numeric value: expected digit (0-9) to follow minus sign, for valid numeric value\n at [Source: (PushbackInputStream); line: 1, column: 
前端如果用x-www-form-urlencoded格式发送请求
  1. 页面会得到错误:
{"timestamp":1604191818105,"status":415,"error":"Unsupported Media Type","message":"Invalid mime type \"application/json, application/x-www-form-urlencoded\": Invalid token character ',' in token \"json, application/x-www-form-urlencoded\"","trace":"org.springframework.web.HttpMediaTypeNotSupportedException: Invalid mime type \"application/json, application/x-www-form-urlencoded\": Invalid token character ',' in token \"json, application/x-www-form-urlencoded\"\r\n\tat 
前端如果用application/json格式发送请求

后台可以正确的接收到参数。

还有种情况就是后台接口定义成post,前端传的参数格式是application/json并且,而且这个接口的参数只需要一个,目前对于这种情况下,我的解决办法是,把需要的这个参数封装到DTO里面去,然后再用@RequestBody来修饰这个DTO作为入参。因为如果这个接口需要的唯一一个参数不放到DTO里面去的话,直接像下面这样的话,@RequestBody不能正确的解析调用该接口传的name字段值。个人理解@RequestBody是用来修饰对象的,而不是基本类型数据的。

@RequestMapping("/post/test2")
@PostMapping
public String testPost2(@RequestBody String name) {
    StudentDTO dto = new StudentDTO();
    dto.setName(name);
    return dto.toString();
}

get请求

首先,get的请求的话,参数都是在请求地址后面拼接参数的方式传参数给后端接口,也就是postman上Params这个方式。所以接口如果是get请求,前端固定是用Params方式传参。所以下面的测试是建立在传参用Params的方式为前提。

后端接口用DTO入参
@RequestMapping("/get/test")
@GetMapping
public String testGETDTO(StudentDTO dto) {
    dto.setId(dto.getId());
    dto.setName(dto.getName());
    return dto.toString();
}

请求得到错误:

{"timestamp":1604193712894,"status":415,"error":"Unsupported Media Type","message":"Invalid mime type \"application/json, application/x-www-form-urlencoded\": Invalid token character ',' in token \"json, application/x-www-form-urlencoded\"","trace":"org.springframework.web.HttpMediaTypeNotSupportedException: Invalid mime type \"application/json, application/x-www-form-urlencoded\": Invalid token character ',' in token \"json, application/x-www-form-urlencoded\"\r\n\tat 
后端接口用DTO并且使用@RequestBody
@RequestMapping("/get/test1")
@GetMapping
public String testGETRequestBody(@RequestBody StudentDTO dto) {
    dto.setId(dto.getId());
    dto.setName(dto.getName());
    return dto.toString();
}

请求得到错误:

{"timestamp":1604195606813,"status":415,"error":"Unsupported Media Type","message":"Invalid mime type \"application/json, application/x-www-form-urlencoded\": Invalid token character ',' in token \"json, application/x-www-form-urlencoded\"","trace":"org.springframework.web.HttpMediaTypeNotSupportedException: Invalid mime type \"application/json, application/x-www-form-urlencoded\": Invalid token character ',' in token \"json, application/x-www-form-urlencoded\"\r\n\tat 
后端接口用基本类型入参,没有用注解
@RequestMapping("/get/test2")
@GetMapping
public String testGET1(Integer id, String name) {
    StudentDTO dto = new StudentDTO();
    dto.setId(id);
    dto.setName(name);
    return dto.toString();
}

后台接收到了数据:

image-20201101095726971

后端接口用基本类型入参,用@RequestParam注解
@RequestMapping("/get/test3")
@GetMapping
public String testGET2(@RequestParam Integer id, @RequestParam String name) {
    StudentDTO dto = new StudentDTO();
    dto.setId(id);
    dto.setName(name);
    return dto.toString();
}
  • 如果请求这个接口的时候,只传了idname,就会报另一个必传参数没有传递的错误,因为@RequestParam注解修饰的参数默认是必传。

    {"timestamp":1604195939558,"status":400,"error":"Bad Request","message":"Required String parameter 'name' is not present","trace":"org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'name' is not present\r\n\tat org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:202)\r\n\tat org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:113)\r\n\tat org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:126)\r\n\tat 
    
  • @RequestParam修饰的参数都传递,则后台接口正确的接收

    image-20201101101403798

总结

  1. 使用接口定义为post请求的时候,并且接收参数格式是application/json的话,则接口的入参用@RequestBody,并且用@RequestBody修饰的参数类型是对象类型,而不是String或者其他基本类型或者基本类型的包装类

  2. 使用get请求的时候,并且请求格式是params(参数拼接在url后面)的话,则接口的入参类型必须是基本类型或基本类型的包装类,注解的话可以用@RequestParam也可以不用,用这个@RequestParam注解的好处是它会校验必传参数。

  3. 题外篇:

    1. 浏览器地址栏发送的请求默认是get请求。
    2. @RequestBody注解做的事情,其实就是按json的格式解析发送的请求写在Body里面的数据。比如用postman的raw方式,然后选择body,然后在body里面按照json格式写请求参数,然后发送请求。
    3. POST请求:可以把参数放到body中,也可以把参数放到url中
    4. GET请求:参数只能放到url中,如果放到body中 服务端从body拿到的是空的,get不适合传输大的参数。

    可以参考:https://www.zhihu.com/question/64312188

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值