Content-Type
1 含义
- http/https发送信息至服务器时的内容编码类型,也称为互联网媒体类型MediaType。Content-Type用于表明发送数据流的类型,服务器根据编码类型使用特定的解析方式,获取数据流中的数据。
2 常见媒体类型
- 以text开头
- text/html : HTML格式
- text/plain :纯文本格式
- text/xml : XML格式
- image/gif :gif图片格式
- image/jpeg :jpg图片格式
- image/png:png图片格式
- 以application开头
- application/xhtml+xml :XHTML格式
- application/xml : XML数据格式
- application/atom+xml :Atom XML聚合格式
- application/json : 请求体中的数据会以JSON字符串的形式发送到后端
- application/pdf :pdf格式
- application/msword : Word文档格式
- application/octet-stream : 二进制流数据(如常见的文件下载)
- application/x-www-form-urlencoded:请求体中的数据会以普通表单形式(键值对)发送后端
- 以multipart开头
- multipart/form-data : 会将请求体的数据处理为一条消息,以标签为单位,用分隔符隔开,既可以上传键值对,也可以上传文件。(常用语文件的上传等操作)
3 @RequestMapping
- 注解内容
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
- 解释
- name:为映射指定名称,可用于类和方法
- value(用的最多):请求的映射地址,是path的别名(@RequestMapping("/foo")等价于@RequestMapping(path="/foo"))
- path:路径映射URI
- method:http请求类型,缩小了映射范围,支持Rest风格请求等
- params:映射请求中的参数值
- headers:映射请求的请求头,只有请求中包含指定的header值,才能处理该请求
- consumes:指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
- produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
- 示例
- name
- value
- value可以为具体值,或者是含有某个变量的一类值(使用@PathVariable可以获取),可以是正则表达式等
- method
spring提供了支持REST风格的注解
- params
只会处理请求中含有名为paramKey,值为paramValue的请求,起到了过滤作用
- headers
会处理headers中含有Referer请求头和值为aaa的请求
- consumes
方法仅处理request Content-Type为“application/json”类型的请求。
- produces
方法仅处理request请求中Accept头中包含了"application/json"的请求,同时暗示了返回的内容类型为application/json(Accept表示浏览器需要接收的media类型)
4 Get/Post请求传参在Spring中接收
4.1 Get/Post区别
- Get和Post都是Http协议的组件,所以底层都是使用tcp链接。
- Get的请求方式是将http的header和data一并发往服务端,也就是一条tcp数据包发送,这就会有两个问题:
- 数据量有限,依赖于Tcp负载能力,所以携带的数据量很大的情况下,容易造成重发。
- 所有的携带的数据只能接受转化成ASCII字符。
- Post不一样,post使用两步走,先发送http的header,然后再传输data。数据类型也不受限制。而且数据隐秘性比较好。
4.2 Get方式参数获取
- Get请求参数是拼接在URL后,限制了数据可以发送的长度。
- 方式
- 默认
@RequestMapping(value = "/getById")
public String getById(Integer id){
}
这种方式就是从请求地址中获取参数名称为id的项,会自动转为Integer类型,但是需要注意的是名称必须大小写一一对应
- @RequestParam
@RequestMapping(value = "/getById")
public String getById(@RequestParam(value = "id",required = false) Integer id){
}
这种@RequestParam方式更加灵活,与默认方式获取参数的原理一样,但是可以改变形参的名称,通过value指定地址参数中的某项,然后可以改变形参的接收变量的名称,同时required属性表示该参数是否必须要在请求中存在,默认为true,如果不存在会报错。
- HttpServletRequest
@RequestMapping(value = "/getById")
public String getById(HttpServletRequest request){
Integer id = Integer.parseInt(request.getParameter("id"));
}
客户端浏览器发出的请求被封装成为一个HttpServletRequest对象,所以我们可以从这个对象中获取到非常多的信息,不仅仅包括Param、headers等等。这里获取Param的方式就是通过调用getParameter方法,传入参数名称即可。
4.3 Post方式参数获取
- 方式
- @RequestBody
@RequestMapping( "/save")
public void save(@RequestBody Map<String,Object> map) {
}
@RequestMapping( "/save")
public void save(@RequestBody String username) {
}
在请求头Headers的Content Type中必须是application/json,这种方式可以直接使用Map,这样就可以将所有参数获取到,然后通过get方法一一获取也可以,或者直接指定具体对象也可以,或者用JSON字符串匹配的实体类接收也可以。
- @RequestParam
@RequestMapping("/save")
public void save(@RequestParam(value = "id",required = false)Integer id) {
}
- 这种方式只用在Content-Type=mutipart/form-data和Content-Type=application/x-www-form-urlencoded这种情况下才能使用,sevlet将Body中的key-value转成Param。
- 如果是这种方式,URL后面拼接Param,也就是类似Get请求的方式,这样的post请求,@RequestParam是可以用的。能够获取后面的参数
- 有趣的现象
- Content-Type=mutipart/form-data,Body中加入参数和URL后面拼接参数一起做Post请求,都可以被加载到Param中,如果是同名的String类型,会将二者拼接;其他类型会取form-data中的值。
- String类型
- 从控制台的打印结果可以看出,同名的参数出现在param和form-data中时,会将二者进行拼接返回
- Integer类型
- Content-Type=application/x-www-form-urlencoded和URL拼接的一起,如果是String类型,则只会取x-www-form-urlencoded的值,其他类型取的是URL拼接的参数。
- String类型
- Integer类型
- HttpServletRequest
- 和Get方式一样,这个方式比较通用
- 如果同时存在param和form-data的话,只会选取form-data中内容
- 但是如果是x-www-from-urlencoded的话,只会取params中的值
- from-urlencoded的话,只会取params中的值