Http--@RequestBody和@RequestParam详解

一、HTTP请求报文解剖

HTTP请求报文由3部分组成(请求行+请求头+请求体):
在这里插入图片描述

下面是一个实际的请求报文:
在这里插入图片描述
①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE。不过,当前的大多数浏览器只支持GET和POST,Spring 3.0提供了一个HiddenHttpMethodFilter,允许你通过“_method”的表单参数指定这些特殊的HTTP方法(实际上还是通过POST提交表单)。服务端配置了HiddenHttpMethodFilter后,Spring会根据_method参数指定的值模拟出相应的HTTP方法,这样,就可以使用这些HTTP方法对处理方法进行映射了。

②为请求对应的URL地址,它和报文头的Host属性组成完整的请求URL,③是协议名称及版本号。

④是HTTP的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。

报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息

  • Accept:text/plain response接受类型

  • Cache-Control: no-cache

  • Accept-Charset:utf-8

  • Authorization:

  • Content-Type: request体类型

  • host: 域名

  • refer: 转发

⑤是报文体,它将一个页面表单中的组件值通过param1=value1&param2=value2的键值对形式编码成一个格式化串,它承载多个请求参数的数据。不但报文体可以传递请求参数,请求URL也可以通过类似于“/chapter15/user.html? param1=value1&param2=value2”的方式传递请求参数。

对照上面的请求报文,我们把它进一步分解,你可以看到一幅更详细的结构图:
在这里插入图片描述

二、我们要知道 GET 请求与 POST 请求的区别
1.GET 请求与 POST 请求的区别
  1. GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连,如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果数据是英文字母或数字,则原样发送;如果是空格,转换为+;如果是中文或其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII码值。而与之对应的,POST把提交的数据放置在HTTP包的包体中。
  2. POST的安全性要比GET的安全性高。注意:这里所说的安全性和上面GET提到的“安全”不是同个概念。上面“安全”的含义仅仅是不作数据修改,而这里安全的含义是真正的Security的含义。比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为:(1)登录页面有可能被浏览器缓存,(2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了,除此之外,使用GET提交数据还可能会造成Cross-site request forgery攻击(CSRF,跨站请求伪造,也被称为:one click attack/session riding)。
    参考:浅谈HTTP中GET、POST用法以及它们的区别

那么在 Spring MVC 中获取 GET 请求与 POST 请求的参数有什么区别呢?

2.获取 GET 请求参数
  1. 默认方式获取参数
@RequestMapping(value = "/message", method = RequestMethod.GET)
public String hello(String msg) {
     return msg;
 }

默认情况下会从URL后面的拼接参数中获取参数名是 msg 的值。
例如:http://localhost:8080/api/message?msg=hello

  1. 使用@RequestParam
@RequestMapping(value = "/message", method = RequestMethod.GET)
public String hello(@RequestParam(value = "msg",required = false) String msg) {
     return msg;
 }
  1. 使用HttpServletRequest
@RequestMapping(value = "/message", method = RequestMethod.GET)
public String hello(HttpServletRequest request) {
     return request.getParameter("msg");
 }

这个方法是获取整个URL的信息,然后手动获取参数。这个里面带的内容很多,不仅请求参数还有Header,Cookies等信息。

3. 获取 POST 请求参数

POST 传递参数可以大致分成两种,一种是表单:在 servlet 实现中mutipart/form-data 和 application/x-www-form-urlencoded 会被特殊处理,请求参数将被放置于request.paramter中解析成map。第二种是 application/json(请求参数放在body体中),参数是存放在json中的,参数必须要用@RequestBody才能解析出来。

  1. 使用@RequestBody
@RequestMapping(value = "/message", method = RequestMethod.POST)
public String hello(@RequestBody String msg) {
    return msg;
}

这种传递方式必须使用Content-Type=application/json,这个不仅可以指定msg为具体对象,也可以用Map、JSONObject、实体对象等。

  1. 使用@RequestParam
@RequestMapping(value = "/message", method = RequestMethod.POST)
public String hello(@RequestParam String msg) {
    return msg;
}

这种方式只用在Content-Type=mutipart/form-data和Content-Type=application/x-www-form-urlencoded这种情况下才能使用,servlet将Body体中的key-value转成参数对。
如果是这种方式,URL后面拼接参数对,也就是类似Get请求的方式,这样的post请求,@RequestParam是能够获取后面的参数。
有一个有趣的现象,如果Content-Type=mutipart/form-data,Body中加入参数和URL后面拼接参数一起做Post请求,都可以被加载到参数对中,如果是同名的,只取用form-data(Body体)中的。
如果Content-Type=application/x-www-form-urlencoded和URL拼接的一起,如果是String类型,则两个值会被拼接,其他类型取的是URL拼接的参数。

  1. 使用 HttpServletRequest
    和Get方式一样,这是个通用的方式。这个也可以和URL拼接的一起搭,但是没有RequestParam的String类型值被拼接问题,优先级 form-data高于URL拼接高于x-www-form-urlencoded。

参考:POST、GET、@RequestBody和@RequestParam区别

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值