HTTP参数传递与接收

基础

软件开发,不同系统之间最常见的数据交互协议是HTTP,客户端【发起请求】并【接收服务端的响应】,服务端【收到请求】并【响应】。

一个HTTP请求分为 【请求行】【请求头】【请求体】三部分,详情参见这里

【请求行】里包含一个URL,该URL可以包含query component部分,即?之后的部分。

【请求行】里还包含本次请求的方式,HTTP常用的请求方式有GET和POST。前者用于客户端获取数据,后者用户客户端提交数据至服务端。二者之间的详细区别见这里

传参

在发起请求的时候,可以携带参数传递给服务端。

GET请求没有请求体,参数只能随URL传递(常见)或随请求头传递(不常见,工程中的请求头一般都是统一封装,为每个请求都设置差异化的请求头比较繁琐)。
GET方式的请求参数以query component的形式传递。query string更加常用,即 query string ≈ query component

POST方式用于将数据发送给服务器,发送的数据置于请求体中(body),而body中的内容类型由Content-Type请求头指定。

Content-Type

The Content-Type entity header is used to indicate the media type.
Content-Type这个请求头/响应头用于表明资源的媒体类型。

  1. In requests, (such as POST or PUT), the client tells the server what type of data is actually sent.
    作为请求头,客户端通过该值告知服务端实际发送的数据类型。
  2. In responses, a Content-Type header tells the client what the content type of the returned content actually is.
    作为响应头,服务端通过该值告知客户端响应体中内容的类型。

MIME

上文提到,Content-Type的值是MIME type
A MIME type (now properly called "media type", but also sometimes "content type") is a string sent along with a file indicating the type of the file (describing the content format, for example, a sound file might be labeled audio/ogg, or an image file image/png).
MIME类型(通常称为“媒体类型”,有时也称为“内容类型”)是与文件一起发送的字符串,用于指定文件类型(描述内容格式,例如,声音文件对应为audio/ogg,图像文件对应为image/png)。

常见的有:

  • application/json:表明内容是Json字符串,参见这里RFC 4627
  • application/x-www-form-urlencoded:键值组由&分割,键与值由=分割,键与值中的非数字字母字符将被百分比编码。因此,该类型不适用与二进制数据传输,参见这里
  • multipart/form-data:每个值作为数据块(body part)发送,客户端代理定义的分隔符(boundary)将每个part分开。 key由每个partContent-Disposition标头中给出。
  • text/plain
  • ...

Servlet

Java EE中,Servlet致力于同客户端进行通信。关于Servlet,可以参见这一篇文章

HttpServletRequest

采用Spring MVC框架,可以将HTTP请求中的信息以一定的方式转换并绑定到控制器类的方法参数中,称之为Spring MVC的数据绑定。

当客户端请求的参数比较简单时,方法形参可以直接使用Spring MVC提供的默认参数类型进行数据绑定,常见的默认类型参数如下:

  • HttpServletRequest:Http请求的Java封装,该接口继承自ServletRequest
  • HttpServletResponse:Http响应的Java封装
  • HttpSession
  • Model/ModelMap

我们这里讨论HTTP参数的接收,因此重点关注HttpServletRequest接口。
该接口由Servlet容器实例化并传递给目标Servlet的doGet/doPost方法,常用方法有:

  • public String getHeader(String name);获取指定请求头
  • public String getMethod();获取请求方式,GET or POST...
  • public String getQueryString();获取queryString,即URL后由?分割的部分。如果不存在,则返回null
  • public Part getPart(String name) throws IOException,ServletException;获取指定名称的part,若不存在返回null。若请求不是multipart/form-data则抛出ServletException

ServletRequest

由上文可知,通过HttpServletRequest接口可以获取到客户端发起的HTTP请求的【请求头】【请求方法】【queryString】等信息。现在继续研究其父类ServletRequest

ServletRequest提供了客户端请求目标Servlet的信息,提供的信息有parameter name and values, attributes, and an input stream..

ServletRequest接口由Servlet容器实例化并传递给目标Servlet的service方法,常用方法有:

  • public String getCharacterEncoding();获取request body中数据的编码方式
  • public int getContentLength();获取request body中的input stream的bytes的长度
  • public String getContentType();获取request body中的Content Type
  • public ServletInputStream getInputStream() throws IOException;使用ServletInputStream以二进制数据的形式检索请求的主体。可以调用此方法或getReader来读取request body中的内容
  • public String getParameter(String name);获取指定的请求参数,若不存在,则返回null。请求参数是请求的额外信息,对于Http Servlet,请求参数存在于queryStringposted form data

Spring MVC数据绑定

由前文讨论可知,理论上,Controller中的方法只有一个HttpServletRequest参数就能够或取到本次请求的所有信息,它相当于一个参数容器。但请求中的参数过多的时候, 势必会存在许多取参的样板代码。

Spring MVC取参过程做了优化。

采用Spring MVC框架,可以将HTTP请求中的信息以一定的方式转换并绑定到控制器类的方法参数中,称之为Spring MVC的数据绑定。

详细的绑定原理及源码分析可以参考这篇文章,本文只讨论具体的操作方法。

服务端接收

参数来源有两个:

  1. ServletRequest#getParameter(String name);取出queryStringposted form data中的参数
  2. ServletRequest#getInputStream();取出request body中的二进制数据

相应的,Spring MVC提供了两种类型的绑定方式

  1. 不使用注解、或配合@RequestParam注解,可绑定默认类型(前文所述四种)、简单数据类型(Integer、Double...)、POJO类型、包装POJO、数组、集合
  2. @RequestBody注解将请求体中的所有内容映射为一个Java对象,此时request body常见的Content-Typeapplication/json,即请求体里的数据是一个json str

客户端传参

开发中常见的客户端有 jquery ajaxaxios、Post Man、Retrofit

其中,ajax和axios都提供了配置类方便自定义。
ajax的请求参数只能配置在data(Data to be sent to the server.)属性中;
axios则提供了paramsdata两个属性用于配置请求参数,data中的内容作为request body发送,而params则是随请求一起发送的普通参数。

其他

  1. 如果key1=value1&key1=value2&key3=value3,则Spring MVC支持将将其绑定为名为key1的数组和名为key1的集合(需要使用@RequestParam注解),HTTP自身允许;
  2. 如果key1=value1,value2,value3,则Spring MVC支持将其绑定为名为key1的数组和名为key1的集合(需要使用@RequestParam注解),Spring MVC的能力扩展;
  3. 如果key1=value1,value2,value3&key1=value4&key1=value5,则Spring MVC支持将其绑定为key1的数组和集合(需要@requestParam注解),结果有3个元素,第一个元素是value1,value2,value3
  4. 如果queryString 的key1=value1但form data的key1=value2,则最终绑定的结果按参数类型而定:如果是String,则value1,value2;如果是数字,则是value1(即queryString优先);如果是容器,则包含两个元素;
  5. js客户端发送请求时指定Content-Typemultipart/form-data的时候,要借助于FormDataAPI。

HTTP请求中的form data和request payload的区别

AJAX POST请求中参数以form data和request payload形式在servlet中的获取方式

传递JSON数据有没有必要用RequestBody?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,064评论 19 139
  • 这个主题其实想了解下SpringMVC的两种不同的参数提交方式和接受方式。 SpringMVC的数据流程图: Js...
    辉蛋儿阅读 11,645评论 1 4
  • SpringMVC学习笔记---- 一、SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导...
    ITsupuerlady阅读 8,409评论 1 34
  • 1.Spring web mvc介绍 Spring web mvc和Struts2都属于表现层的框架,它是Spri...
    七弦桐语阅读 13,987评论 2 38
  • 转我的朋友: 真情告白 我是郭老师…… “大自然这本书是用数学语言写的”,意大利哲学家、天文学家伽利略也曾说过:“...
    王自成阅读 1,715评论 0 0

友情链接更多精彩内容