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中的值