1、 Http請(qǐng)求報(bào)文
Http請(qǐng)求報(bào)文示例圖如下:
?
-
①是請(qǐng)求方法,GET和POST是最常見(jiàn)的HTTP方法,除此以外還包括DELETE、HEAD、OPTIONS、PUT、TRACE。不過(guò),當(dāng)前的大多數(shù)瀏覽器只支持GET和POST,Spring 3.0提供了一個(gè)HiddenHttpMethodFilter,允許通過(guò)_method的表單參數(shù)指定這些特殊的HTTP方法(實(shí)際上還是通過(guò)POST提交表單)。服務(wù)端配置了HiddenHttpMethodFilter后,Spring會(huì)根據(jù)_method參數(shù)指定的值模擬出相應(yīng)的HTTP方法,這樣,就可以使用這些HTTP方法對(duì)處理方法進(jìn)行映射了。
-
②為請(qǐng)求對(duì)應(yīng)的URL地址,它和報(bào)文頭的Host屬性組成完整的請(qǐng)求URL
-
③是協(xié)議名稱(chēng)及版本號(hào)
-
④是HTTP的報(bào)文頭,報(bào)文頭包含若干個(gè)屬性,格式為 屬性名:屬性值 ,服務(wù)端據(jù)此獲取客戶端的信息
-
⑤是報(bào)文體,它將一個(gè)頁(yè)面表單中的組件值通過(guò)param1=value1¶m2=value2的鍵值對(duì)形式編碼成一個(gè)格式化串,它承載多個(gè)請(qǐng)求參數(shù)的數(shù)據(jù)。不但報(bào)文體可以傳遞請(qǐng)求參數(shù),請(qǐng)求URL也可以通過(guò)類(lèi)似于/chapter15/user.html? param1=value1¶m2=value2”的方式傳遞請(qǐng)求參數(shù)。
對(duì)照上面的請(qǐng)求報(bào)文,把它進(jìn)一步分解,可以看到一幅更詳細(xì)的結(jié)構(gòu)圖:
2、post/get請(qǐng)求
2.1、post請(qǐng)求
Http Header里的Content-Type一般有這三種:
multipart/form-data(一般用來(lái)上傳文件): 數(shù)據(jù)被編碼為一條消息,頁(yè)面上的每個(gè)控件對(duì)應(yīng)消息中的一個(gè)部分;
application/x-www-form-urlencoded:數(shù)據(jù)被編碼為名稱(chēng)/值對(duì)。這是標(biāo)準(zhǔn)的編碼格式。默認(rèn)行為。會(huì)將表單內(nèi)的數(shù)據(jù)轉(zhuǎn)換拼接成key-value對(duì)(非 ASCII 碼進(jìn)行編碼);
text/plain: 數(shù)據(jù)以純文本形式(text/json/xml/html)進(jìn)行編碼,其中不含任何控件或格式字符。postman軟件里標(biāo)的是RAW;
2.2、get請(qǐng)求
GET請(qǐng)求 不存在請(qǐng)求實(shí)體部分,鍵值對(duì)參數(shù)放置在 URL 尾部,瀏覽器把form數(shù)據(jù)轉(zhuǎn)換成一個(gè)字串name1=value1&name2=value2...,然后把這個(gè)字串追加到url后面,用?分割,加載這個(gè)新的url。因此請(qǐng)求頭不需要設(shè)置 Content-Type 字段,就算設(shè)置了沒(méi)什么用,還是用默認(rèn)的content-type來(lái)進(jìn)行的: application/x-www-form-urlencoded;
非 ASCII 碼會(huì)自動(dòng)進(jìn)行編碼轉(zhuǎn)換,例如發(fā)送請(qǐng)求:www.bilibili.com?hehe=你的我的
GET 參數(shù)的編碼方式是無(wú)法人為干涉的 ,這導(dǎo)致了不同瀏覽器有不同的編碼方式,因此最穩(wěn)妥的方案是人工預(yù)編碼,人工解碼,從而禁止瀏覽器編碼的干涉
2.3 post VS get
Get和Post都是Http協(xié)議的組件,所以底層都是使用tcp鏈接。Get的請(qǐng)求方式是將http的header和data一并發(fā)往服務(wù)端,也就是一條tcp數(shù)據(jù)包發(fā)送,這就會(huì)有兩個(gè)問(wèn)題:
數(shù)據(jù)量有限,依賴于Tcp負(fù)載能力,所以攜帶的數(shù)據(jù)量很大的情況下,容易造成重發(fā)。
所有的攜帶的數(shù)據(jù)只能接受轉(zhuǎn)化成ASCII字符。
但是Post不一樣,post使用兩步走,先發(fā)送http的header,然后再傳輸data。數(shù)據(jù)類(lèi)型也不受限制。而且數(shù)據(jù)隱秘性比較好。
3、后端獲取請(qǐng)求參數(shù)
3.1、post請(qǐng)求
- 使用HttpServletRequest
@PostMapping("/uploadNetPointExcelFile")
public Result uploadNetPointExcelFile(HttpServletRequest request) {
String userId= request.getParameter("userId");
}
- 使用@RequestBody 可接受的參數(shù) Map,JSONObject,或者對(duì)應(yīng)的JavaBean
//post 請(qǐng)求的是json字符串,@RequestBody 將字符串轉(zhuǎn)為Map<>類(lèi)型
//post : {"key":"value"}
@RequestMapping(value = "/test")
public String getStart1(@RequestBody Map<String,String> map) {
return map.toString();
}
- 使用@RequestParam
//這種方式只用在Content-Type=application/x-www-form-urlencoded這種情況下才能使用,sevlet將Body中的key-value轉(zhuǎn)成Param。
@RequestMapping(value = "/getUserInfo")
public User getUserInfo(@RequestParam(value = "id",required = false) Integer id){
}
總結(jié):post可以傳遞參數(shù)可以大致分成兩種,
一種是表單:在sevlet實(shí)現(xiàn)中mutipart/form-data和application/x-www-form-urlencoded會(huì)被特殊處理,請(qǐng)求參數(shù)將被放置于request.paramter,解析成map,參數(shù)必須要用@RequestParam解析;
第二種是application/json,參數(shù)是存放在json中的,參數(shù)必須要用@RequestBody才能解析出來(lái)。
@RequestBody是將post請(qǐng)求中內(nèi)容轉(zhuǎn)為一個(gè)整體對(duì)象。
@RequestBody的解析有兩個(gè)條件:
1.POST請(qǐng)求中content的值必須為json格式(存儲(chǔ)形式可以是字符串,也可以是byte數(shù)組);
2.@RequestBody注解的參數(shù)類(lèi)型必須是完全可以接收參數(shù)值的類(lèi)型,比如:Map,JSONObject,或者對(duì)應(yīng)的JavaBean;
3.2、get請(qǐng)求
get請(qǐng)求方式參數(shù)是拼接在url后,所以限制了可以發(fā)送的長(zhǎng)度。Get不支持使用http Body獲取參數(shù),他只支持params,也就是URL拼接參數(shù)
- 使用HttpServletRequest
@GetMapping("/downloadJoinRecord")
public void downloadJoinRecord(HttpServletRequest request, HttpServletResponse response) {
String activityName = request.getParameter("activityName");
String productType = request.getParameter("productType");
}
這個(gè)方法是獲取整個(gè)URL的信息,然后手動(dòng)獲取和分離參數(shù),和類(lèi)型轉(zhuǎn)化。這個(gè)里面帶的內(nèi)容很多,不僅Param還有Header,Cookies等。
- 默認(rèn)方式,什么也不加,直接在方法中獲取參數(shù)值
//參數(shù)多時(shí),用對(duì)象接收
@GetMapping("/exportAnalysisNew")
public void exportAnalysisNew(GoldFingerClueReportDTO paramMap, HttpServletResponse response, HttpServletRequest request){
}
//參數(shù)少時(shí),直接接收
@RequestMapping(value = "/getUserInfo")
public User getUserInfo(Integer id){
}
//默認(rèn)情況下會(huì)從Param(就是URL后面的拼接參數(shù))獲取名字是id的項(xiàng),自動(dòng)轉(zhuǎn)化成Integer類(lèi)型,其他的類(lèi)型也是類(lèi)似。
- 利用@RequestParam
@GetMapping("getUserName")
public Result getTest(@RequestParam("userName") String userName){
return userName;
}
4、@RequestBody VS @RequestParam
4.1、@RequestBody
@RequestBody用來(lái)處理請(qǐng)求頭Content-Type: 為 application/json編碼的內(nèi)容,明確的告訴服務(wù)器發(fā)送的內(nèi)容是json。
因?yàn)樾枰x取body中內(nèi)容,所以只能接受post請(qǐng)求。
就application/json類(lèi)型的數(shù)據(jù)而言,使用注解@RequestBody可以將body里面所有的json數(shù)據(jù)傳到后端,后端再進(jìn)行解析。
GET請(qǐng)求中,因?yàn)闆](méi)有HttpEntity,所以@RequestBody并不適用。
POST請(qǐng)求中,通過(guò)HttpEntity傳遞的參數(shù),必須要在請(qǐng)求頭中聲明數(shù)據(jù)的類(lèi)型Content-Type,SpringMVC通過(guò)使用HandlerAdapter 配置的HttpMessageConverters來(lái)解析HttpEntity中的數(shù)據(jù),然后綁定到相應(yīng)的bean上。
4.2 @RequestParam
@RequestParam用來(lái)處理請(qǐng)求頭Content-Type: 為 application/x-www-form-urlencoded編碼的內(nèi)容。(Http協(xié)議中,如果不指定Content-Type,則默認(rèn)傳遞的參數(shù)就是application/x-www-form-urlencoded類(lèi)型)
get 方式中queryString的值,和post方式中 body data的值都會(huì)被Servlet接受到并轉(zhuǎn)化到Request.getParameter()參數(shù)集中,所以@RequestParam可以獲取的到。
RequestParam可以接受簡(jiǎn)單類(lèi)型的屬性,也可以接受對(duì)象類(lèi)型。
實(shí)質(zhì)是將Request.getParameter() 中的Key-Value參數(shù)Map利用Spring的轉(zhuǎn)化機(jī)制ConversionService配置,轉(zhuǎn)化成參數(shù)接收對(duì)象或字段。
@RequestParam有三個(gè)配置參數(shù):
- required 表示是否必須,默認(rèn)為 true,必須。
- defaultValue 可設(shè)置請(qǐng)求參數(shù)的默認(rèn)值。
- value 為接收url的參數(shù)名(相當(dāng)于key值)。
@RequestParam也可用于其它類(lèi)型的請(qǐng)求,例如:POST、DELETE等請(qǐng)求。
5、總結(jié)
-
form-data、x-www-form-urlencoded:不可以用@RequestBody;可以用@RequestParam
-
application/json:json字符串部分可以用@RequestBody;url中的?后面參數(shù)可以用@RequestParam
-
在GET請(qǐng)求中,不能使用@RequestBody。 在POST請(qǐng)求,可以使用@RequestBody和@RequestParam;
-
可以使用多個(gè)@RequestParam獲取數(shù)據(jù),@RequestBody不可以;
-
參數(shù)在url中時(shí),使用@PathVariable
接口規(guī)范為resultful風(fēng)格時(shí),舉個(gè)例子:如果要獲取某個(gè)id下此條問(wèn)題答案的查詢次數(shù)的話,則后臺(tái)就需要?jiǎng)討B(tài)獲取參數(shù),其注解為@PathVariable,并且requestMapping中的value應(yīng)為value="/{id}/queryNum",截圖如下:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-822160.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-822160.html
到了這里,關(guān)于Http中post/get請(qǐng)求參數(shù)接收的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!