HTTP參數(shù)傳遞與接收

基礎(chǔ)

軟件開發(fā)时捌,不同系統(tǒng)之間最常見的數(shù)據(jù)交互協(xié)議是HTTP梯皿,客戶端【發(fā)起請(qǐng)求】并【接收服務(wù)端的響應(yīng)】怔昨,服務(wù)端【收到請(qǐng)求】并【響應(yīng)】挫酿。

一個(gè)HTTP請(qǐng)求分為 【請(qǐng)求行】【請(qǐng)求頭】【請(qǐng)求體】三部分余赢,詳情參見這里芯义。

【請(qǐng)求行】里包含一個(gè)URL,該URL可以包含query component部分妻柒,即?之后的部分扛拨。

【請(qǐng)求行】里還包含本次請(qǐng)求的方式,HTTP常用的請(qǐng)求方式有GET和POST举塔。前者用于客戶端獲取數(shù)據(jù)绑警,后者用戶客戶端提交數(shù)據(jù)至服務(wù)端。二者之間的詳細(xì)區(qū)別見這里央渣。

傳參

在發(fā)起請(qǐng)求的時(shí)候计盒,可以攜帶參數(shù)傳遞給服務(wù)端。

GET請(qǐng)求沒有請(qǐng)求體芽丹,參數(shù)只能隨URL傳遞(常見)或隨請(qǐng)求頭傳遞(不常見北启,工程中的請(qǐng)求頭一般都是統(tǒng)一封裝,為每個(gè)請(qǐng)求都設(shè)置差異化的請(qǐng)求頭比較繁瑣)拔第。
GET方式的請(qǐng)求參數(shù)以query component的形式傳遞咕村。query string更加常用,即 query string ≈ query component楼肪。

POST方式用于將數(shù)據(jù)發(fā)送給服務(wù)器培廓,發(fā)送的數(shù)據(jù)置于請(qǐng)求體中(body),而body中的內(nèi)容類型由Content-Type請(qǐng)求頭指定春叫。

Content-Type

The Content-Type entity header is used to indicate the media type.
Content-Type這個(gè)請(qǐng)求頭/響應(yīng)頭用于表明資源的媒體類型肩钠。

  1. In requests, (such as POST or PUT), the client tells the server what type of data is actually sent.
    作為請(qǐng)求頭,客戶端通過該值告知服務(wù)端實(shí)際發(fā)送的數(shù)據(jù)類型暂殖。
  2. In responses, a Content-Type header tells the client what the content type of the returned content actually is.
    作為響應(yīng)頭价匠,服務(wù)端通過該值告知客戶端響應(yīng)體中內(nèi)容的類型。

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類型(通常稱為“媒體類型”,有時(shí)也稱為“內(nèi)容類型”)是與文件一起發(fā)送的字符串晨横,用于指定文件類型(描述內(nèi)容格式洋腮,例如箫柳,聲音文件對(duì)應(yīng)為audio/ogg,圖像文件對(duì)應(yīng)為image/png)啥供。

常見的有:

  • application/json:表明內(nèi)容是Json字符串悯恍,參見這里RFC 4627
  • application/x-www-form-urlencoded:鍵值組由&分割,鍵與值由=分割伙狐,鍵與值中的非數(shù)字字母字符將被百分比編碼涮毫。因此,該類型不適用與二進(jìn)制數(shù)據(jù)傳輸贷屎,參見這里
  • multipart/form-data:每個(gè)值作為數(shù)據(jù)塊(body part)發(fā)送罢防,客戶端代理定義的分隔符(boundary)將每個(gè)part分開。 key由每個(gè)partContent-Disposition標(biāo)頭中給出唉侄。
  • text/plain
  • ...

Servlet

Java EE中咒吐,Servlet致力于同客戶端進(jìn)行通信。關(guān)于Servlet美旧,可以參見這一篇文章渤滞。

HttpServletRequest

采用Spring MVC框架,可以將HTTP請(qǐng)求中的信息以一定的方式轉(zhuǎn)換并綁定到控制器類的方法參數(shù)中榴嗅,稱之為Spring MVC的數(shù)據(jù)綁定。

當(dāng)客戶端請(qǐng)求的參數(shù)比較簡(jiǎn)單時(shí)陶舞,方法形參可以直接使用Spring MVC提供的默認(rèn)參數(shù)類型進(jìn)行數(shù)據(jù)綁定嗽测,常見的默認(rèn)類型參數(shù)如下:

  • HttpServletRequest:Http請(qǐng)求的Java封裝肿孵,該接口繼承自ServletRequest
  • HttpServletResponse:Http響應(yīng)的Java封裝
  • HttpSession
  • Model/ModelMap

我們這里討論HTTP參數(shù)的接收唠粥,因此重點(diǎn)關(guān)注HttpServletRequest接口。
該接口由Servlet容器實(shí)例化并傳遞給目標(biāo)Servlet的doGet/doPost方法停做,常用方法有:

  • public String getHeader(String name);獲取指定請(qǐng)求頭
  • public String getMethod();獲取請(qǐng)求方式晤愧,GET or POST...
  • public String getQueryString();獲取queryString,即URL后由?分割的部分蛉腌。如果不存在官份,則返回null
  • public Part getPart(String name) throws IOException,ServletException;獲取指定名稱的part,若不存在返回null烙丛。若請(qǐng)求不是multipart/form-data則拋出ServletException

ServletRequest

由上文可知舅巷,通過HttpServletRequest接口可以獲取到客戶端發(fā)起的HTTP請(qǐng)求的【請(qǐng)求頭】【請(qǐng)求方法】【queryString】等信息。現(xiàn)在繼續(xù)研究其父類ServletRequest河咽。

ServletRequest提供了客戶端請(qǐng)求目標(biāo)Servlet的信息钠右,提供的信息有parameter name and values, attributes, and an input stream..

ServletRequest接口由Servlet容器實(shí)例化并傳遞給目標(biāo)Servlet的service方法,常用方法有:

  • public String getCharacterEncoding();獲取request body中數(shù)據(jù)的編碼方式
  • public int getContentLength();獲取request body中的input stream的bytes的長度
  • public String getContentType();獲取request body中的Content Type
  • public ServletInputStream getInputStream() throws IOException;使用ServletInputStream以二進(jìn)制數(shù)據(jù)的形式檢索請(qǐng)求的主體忘蟹§浚可以調(diào)用此方法或getReader來讀取request body中的內(nèi)容
  • public String getParameter(String name);獲取指定的請(qǐng)求參數(shù)搁凸,若不存在,則返回null狠毯。請(qǐng)求參數(shù)是請(qǐng)求的額外信息坪仇,對(duì)于Http Servlet,請(qǐng)求參數(shù)存在于queryStringposted form data

Spring MVC數(shù)據(jù)綁定

由前文討論可知垃你,理論上椅文,Controller中的方法只有一個(gè)HttpServletRequest參數(shù)就能夠或取到本次請(qǐng)求的所有信息,它相當(dāng)于一個(gè)參數(shù)容器惜颇。但請(qǐng)求中的參數(shù)過多的時(shí)候皆刺, 勢(shì)必會(huì)存在許多取參的樣板代碼。

Spring MVC取參過程做了優(yōu)化凌摄。

采用Spring MVC框架羡蛾,可以將HTTP請(qǐng)求中的信息以一定的方式轉(zhuǎn)換并綁定到控制器類的方法參數(shù)中,稱之為Spring MVC的數(shù)據(jù)綁定锨亏。

詳細(xì)的綁定原理及源碼分析可以參考這篇文章痴怨,本文只討論具體的操作方法。

服務(wù)端接收

參數(shù)來源有兩個(gè):

  1. ServletRequest#getParameter(String name);取出queryStringposted form data中的參數(shù)
  2. ServletRequest#getInputStream();取出request body中的二進(jìn)制數(shù)據(jù)

相應(yīng)的器予,Spring MVC提供了兩種類型的綁定方式

  1. 不使用注解浪藻、或配合@RequestParam注解,可綁定默認(rèn)類型(前文所述四種)乾翔、簡(jiǎn)單數(shù)據(jù)類型(Integer爱葵、Double...)、POJO類型反浓、包裝POJO萌丈、數(shù)組、集合
  2. @RequestBody注解將請(qǐng)求體中的所有內(nèi)容映射為一個(gè)Java對(duì)象雷则,此時(shí)request body常見的Content-Typeapplication/json辆雾,即請(qǐng)求體里的數(shù)據(jù)是一個(gè)json str

客戶端傳參

開發(fā)中常見的客戶端有 jquery ajaxaxios月劈、Post Man度迂、Retrofit

其中,ajax和axios都提供了配置類方便自定義艺栈。
ajax的請(qǐng)求參數(shù)只能配置在data(Data to be sent to the server.)屬性中英岭;
axios則提供了paramsdata兩個(gè)屬性用于配置請(qǐng)求參數(shù),data中的內(nèi)容作為request body發(fā)送湿右,而params則是隨請(qǐng)求一起發(fā)送的普通參數(shù)诅妹。

其他

  1. 如果key1=value1&key1=value2&key3=value3,則Spring MVC支持將將其綁定為名為key1的數(shù)組和名為key1的集合(需要使用@RequestParam注解),HTTP自身允許吭狡;
  2. 如果key1=value1,value2,value3尖殃,則Spring MVC支持將其綁定為名為key1的數(shù)組和名為key1的集合(需要使用@RequestParam注解),Spring MVC的能力擴(kuò)展划煮;
  3. 如果key1=value1,value2,value3&key1=value4&key1=value5送丰,則Spring MVC支持將其綁定為key1的數(shù)組和集合(需要@requestParam注解),結(jié)果有3個(gè)元素弛秋,第一個(gè)元素是value1,value2,value3器躏;
  4. 如果queryString 的key1=value1但form data的key1=value2,則最終綁定的結(jié)果按參數(shù)類型而定:如果是String蟹略,則value1,value2登失;如果是數(shù)字,則是value1(即queryString優(yōu)先)挖炬;如果是容器揽浙,則包含兩個(gè)元素;
  5. js客戶端發(fā)送請(qǐng)求時(shí)指定Content-Typemultipart/form-data的時(shí)候意敛,要借助于FormDataAPI馅巷。

HTTP請(qǐng)求中的form data和request payload的區(qū)別

AJAX POST請(qǐng)求中參數(shù)以form data和request payload形式在servlet中的獲取方式

傳遞JSON數(shù)據(jù)有沒有必要用RequestBody?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末草姻,一起剝皮案震驚了整個(gè)濱河市钓猬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌碴倾,老刑警劉巖逗噩,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異跌榔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)捶障,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門僧须,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巍耗,“玉大人扣甲,你說我怎么就攤上這事∶⒙剩” “怎么了锭部?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵暂论,是天一觀的道長。 經(jīng)常有香客問我拌禾,道長取胎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮闻蛀,結(jié)果婚禮上匪傍,老公的妹妹穿的比我還像新娘。我一直安慰自己觉痛,他們只是感情好役衡,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著薪棒,像睡著了一般手蝎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上俐芯,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天棵介,我揣著相機(jī)與錄音,去河邊找鬼泼各。 笑死鞍时,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的扣蜻。 我是一名探鬼主播逆巍,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼莽使!你這毒婦竟也來了锐极?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤芳肌,失蹤者是張志新(化名)和其女友劉穎灵再,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亿笤,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡翎迁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了净薛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汪榔。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肃拜,靈堂內(nèi)的尸體忽然破棺而出痴腌,到底是詐尸還是另有隱情,我是刑警寧澤燃领,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布士聪,位于F島的核電站,受9級(jí)特大地震影響猛蔽,放射性物質(zhì)發(fā)生泄漏剥悟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望懦胞。 院中可真熱鬧替久,春花似錦、人聲如沸躏尉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胀糜。三九已至颅拦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間教藻,已是汗流浹背距帅。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留括堤,地道東北人碌秸。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像悄窃,于是被迫代替她去往敵國和親讥电。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理轧抗,服務(wù)發(fā)現(xiàn)恩敌,斷路器,智...
    卡卡羅2017閱讀 134,656評(píng)論 18 139
  • 這個(gè)主題其實(shí)想了解下SpringMVC的兩種不同的參數(shù)提交方式和接受方式横媚。 SpringMVC的數(shù)據(jù)流程圖: Js...
    輝蛋兒閱讀 6,660評(píng)論 1 4
  • SpringMVC學(xué)習(xí)筆記---- 一纠炮、SpringMVC基礎(chǔ)入門,創(chuàng)建一個(gè)HelloWorld程序 1.首先灯蝴,導(dǎo)...
    ITsupuerlady閱讀 3,121評(píng)論 1 34
  • 1.Spring web mvc介紹 Spring web mvc和Struts2都屬于表現(xiàn)層的框架,它是Spri...
    七弦桐語閱讀 11,516評(píng)論 2 38
  • 轉(zhuǎn)我的朋友: 真情告白 我是郭老師…… “大自然這本書是用數(shù)學(xué)語言寫的”恢口,意大利哲學(xué)家、天文學(xué)家伽利略也曾說過:“...
    王自成閱讀 236評(píng)論 0 0