参考 前后端分离的项目中,后台采用springboot,使用Restful风格设计接口,在GET请求下,如果后台使用@RequestBody注解接受参数,则会报错,而在POST请求下,如果后台使用@RequestParam注解接受参数也会报错。
一、GET与POST请求之间的差别
- Get和Post都是Http协议的组件,所以底层都是使用tcp链接。Get的请求方式是将http的header和data一并发往服务端,也就是一条tcp数据包发送,这就会有两个问题:
- 数据量有限,依赖于Tcp负载能力,所以携带的数据量很大的情况下,容易造成重发。所有的携带的数据只能接受转化成ASCII字符。
- 但是Post不一样,post使用两步走,先发送http的header,然后再传输data。数据类型也不受限制。而且数据隐秘性比较好。
二、GET参数获取方式
get请求方式参数是拼接在url后,所以限制了可以发送的长度。Get不支持使用http Body获取参数,他只支持params,也就是URL拼接参数。如https://editor.csdn.net/md?articleId=107617370get请求接受参数的标准就是使用url方式传参,如果请求参数过于复杂,理论上不推荐使用get方式传参,毕竟get传参还具有长度的限制
- 默认方式
- 使用@RequestParam注解
- 使用HttpServletRequest
@RequestMapping(value = "/getUserInfo")
public User getUserInfo(HttpServletRequest request){
Integer id = Integer.parseInt(request.getParameter("id"));
if (id.intValue() == 0) {
return null;
}
}
这个方法是获取整个URL的信息,然后手动获取和分离参数,和类型转化。这个里面带的内容很多,不仅Param还有Header,Cookies等。
三、POST方式传递参数
- post可以传递参数可以大致分成两种,一种是表单:在sevlet实现中mutipart/form-data和application/x-www-form-urlencoded会被特殊处理,请求参数将被放置于request.paramter,解析成map。第二种,已application/json,参数是存放在json中的,参数必须要用@RequestBody才能解析出来。
- @RequestBody
- @RequestBody是将post请求中内容转为一个整体对象。
- @RequestBody的解析有两个条件:
1. POST请求中content的值必须为json格式(存储形式可以是字符串,也可以是byte数组);
2. @RequestBody注解的参数类型必须是完全可以接收参数值的类型,比如:Map,JSONObject,或者对应的JavaBean;
所以Integer类型不能作为@RequestBody注解的参数类型
application/x-www-form-urlencoded : 中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
- @RequestParam
- 这种方式只用在Content-Type=application/x-www-form-urlencoded这种情况下才能使用,sevlet将Body中的key-value转成Param。
- 有一个有趣的现象,如果Content-Type=mutipart/form-data,Body中加入参数和URL后面拼接参数一起做Post请求,都可以被加载到Param中,如果是同名的,只取用form-data中的。
- 如果Content-Type=application/x-www-form-urlencoded和URL拼接的一起,如果是String类型,则两个值会被拼接,其他类型取的是URL拼接的参数。
- application/x-www-form-urlencoded : 中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
- 通用HttpServletRequest
- 和Get方式一样,这是个通用的方式。这个也可以和URL拼接的一起搭,但是没有RequestParam的String类型值被拼接问题,优先级 form-data高于URL拼接高于x-www-form-urlencoded。