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閱讀 227,748評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,165評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,595評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,633評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,435評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,943評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,035評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,175評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,713評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,599評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,788評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,303評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,034評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,412評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,664評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,408評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,747評論 2 370

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,778評論 18 139
  • 這個主題其實想了解下SpringMVC的兩種不同的參數提交方式和接受方式。 SpringMVC的數據流程圖: Js...
    輝蛋兒閱讀 6,671評論 1 4
  • SpringMVC學習筆記---- 一、SpringMVC基礎入門,創建一個HelloWorld程序 1.首先,導...
    ITsupuerlady閱讀 3,136評論 1 34
  • 1.Spring web mvc介紹 Spring web mvc和Struts2都屬于表現層的框架,它是Spri...
    七弦桐語閱讀 11,530評論 2 38
  • 轉我的朋友: 真情告白 我是郭老師…… “大自然這本書是用數學語言寫的”,意大利哲學家、天文學家伽利略也曾說過:“...
    王自成閱讀 240評論 0 0