@requestbody和@requestparam到底什么作用

x33g5p2x  于2022-01-13 转载在 其他  
字(4.4k)|赞(0)|评价(0)|浏览(522)

1、什么都不写

GET

可以自动封装为对象模型,没有的数值自动为0值

POST

请求体里面放了数据,但是还是使用了RequestParam里的数据

总结:

在不使用注解的情况下,相当于默认使用了RequestParam里的数据 (这种理解是错误的,真实的原因参考下面段落 有一个有趣的现象 ),而且可以自动封装为对象模型,没有的数据也不会报错,而是设为0值
post请求时,如果不使用 contentType:'application/json;charset=utf-8',参数还是可以在RequestParam里获取,所以也可以封装为对象模型。

2、使用@RequestParam

GET POST

结果都是400:Required Student parameter ‘student’ is not present
使用@RequsetParam时,无法封装对象模型,只能接受简单数据类型(String int 等)。
值得注意的是如果使用@RequestParam(required = false),在没有对应数据时不会报400错误,而是赋为0值。

3、使用@RequestBody

GET

结果400:The request sent by the client was syntactically incorrect.
使用get请求没有请求体,而使用@RequestBody获取的肯定是请求体里的数据

POST

结果415:The server refused this request because the request entity is in a format not supported by the requested resource for the requested method.
因为Http协议中,如果不指定Content-Type,则默认传递的参数就是application/x-www-form-urlencoded类型。使用@RequestBody必须使用 contentType:'application/json;charset=utf-8' ,且只能是post请求。

结果:{“name”:“lisi”,“no”:“001”,“age”:12}
将Content-Type手动设置为json格式,可以把请求体里的json字符串,读出来封装为对象模型。

总结

不写注解,默认使用RequestParam里的数据,而且没有的话也不报错,读为0值;
@RequestParam使用的是RequestParam里的数据。key和变量名必须一致,否则报错。无法封装对象模型接受参数;
@RequestBody使用的是请求体里的数据,必须使用json格式,需要在请求体里面设置Content-Type:application/json;

结果:{“name”:“zhangsan”,“no”:“001”,“age”:12}
使用了RequestParam的name,RequestBody的no和age。

另外

结果与上方一致。{“name”:“zhangsan”,“no”:“001”,“age”:12}
因为url路径后面的值都会被Servlet接受到并转化到Request.getParameter()参数集中(HttpServletRequest request),所以@RequestParam可以获取的到。即request.getParameter(" ")能得到的数据使用@RequestParam也可以得到

-----------------分割线------------------------------------------------------------------------------

之前理解的太片面。工作中有遇到了上面结论解释不了的情况,使用post请求,但是参数能从RequestParam里面获取。不得不再次开始查资料。
首先应该理解:Query String Parameters、Form Data、Request Payload的区别
参考:https://blog.csdn.net/c_liufeng/article/details/89228115

发起一次POST请求时,若未指定content-type,则默认content-type为application/x-www-form-urlencoded。即参数会以Form Data的形式进行传递,不会显式出现在请求url中。请求参数将被放置于request.paramter,解析成map。在控制台看到,数据就是在Form Data中。form表单中数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式为application/x-www-form-urlencoded)。
所以url、Query String Parameters、Form Data里的参数都可以通过@RequestParam或者request.getParameter(" ")获取。

@RequestBody

@RequestBody是将post请求中内容转为一个整体对象。
@RequestBody的解析有两个条件:

  1. POST请求中content的值必须为json格式(存储形式可以是字符串,也可以是byte数组); contentType:'application/json;charset=utf-8'
  2. @RequestBody注解的参数类型必须是完全可以接收参数值的类型,比如:Map,JSONObject,或者对应的JavaBean;
    所以Integer类型不能作为@RequestBody注解的参数类型
@RequestParam

这种方式只用在Content-Type=application/x-www-form-urlencoded这种情况下才能使用,sevlet将Body中的key-value转成Param。
有一个有趣的现象

  1. 如果Content-Type=application/x-www-form-urlencoded,url和body中有相同的属性名。如果是String类型,则两个值会被拼接,其他类型取的是URL拼接的参数。
$.ajax({
     type: "post",
     contentType: "application/x-www-form-urlencoded",
     url: "xhh/add.do?name=zhangsan&age=90",
     data:  data.field,
     dataType: "json",
     success: function (data) {

     alert(data.toString());
 }
@RequestMapping(value = "/add.do", method = {RequestMethod.POST})
    public String test(@RequestParam("name") String name,
     @RequestParam("age") int age){
        System.out.println("name:" + name);
        System.out.println("age" + age);
        return name;
    }

后台打印结果:

name:zhangsan,qqq
age:90
  1. 如果Content-Type=mutipart/form-data,Body中加入参数和URL后面拼接参数一起做Post请求,都可以被加载到Param中,如果是同名的,只取用form-data中的。
$.ajax({
type: "post",
contentType: "mutipart/form-data",
url: "xhh/add.do?name=zhangsan&age=90",
data:  data.field,
dataType: "json",
success: function (data) {

alert(data.toString());
}

控制层代码同上
前端传参同上

后台打印结果:

name:zhangsan
age:90
  1. get请求,结果与上面2个并不完全相同,至于是获取url数据还是Query String Parameters里数据,还是拼接,具体情况再具体测吧,总之避免这种情况出现最好。

application/x-www-form-urlencoded : 表单中默认的ContentType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)

通用HttpServletRequest

和Get方式一样,这是个通用的方式。这个也可以和URL拼接的一起搭,但是没有RequestParam的String类型值被拼接问题,优先级 form-data高于URL拼接高于x-www-form-urlencoded。
参考:https://blog.csdn.net/qq_43194157/article/details/107617370

后端如果用springMVC的@RequestBody注解的话,则只能接收Json对象的字符串,不能接收Json对象,用 JSON.stringify(data)的方式将对象变成字符串,同时ajax请求也要指定dataType: “json”,contentType:“application/json” ,这样就能用@RequestBody注解绑定对象或者List集合.

参考:https://blog.csdn.net/weixin_38676276/article/details/87630740

这次得出的结论:
1.@RequestBody只能用来接受Json格式的字符串,前端必须使用 contentType:'application/json;charset=utf-8' ,必须是post请求。
2.@RequestParam或者没有注解获取的都是requestParam(除了contentType:'application/json;charset=utf-8'时,其他情况下参数都会被封装在requestParam里。如果url和body里面都有重名的参数,参考 有一个有趣的现象 那里)里的数据。不管是对象模型里的属性(即使用对象模型接收参数的时候),还是基本数据类型都一样。
区别是没有注解的情况下相当使用了@RequestParam(required = false) ,不传不会报错,给0值。

相关文章