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?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,264评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,549评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,389评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,616评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,461评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,351评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,776评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,414评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,722评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,760评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,537评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,381评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,787评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,030评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,304评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,734评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,943评论 2 336

推荐阅读更多精彩内容

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