常見的一個web服務,如何獲取請求參數?java
通常最多見的請求爲GET和POST,get請求的參數在url上能夠獲取,post請求參數除了url上還有可能在表單中,文件上傳時,獲取方式又和通常的參數獲取不同web
本篇則主要集中在不一樣請求方式下,獲取參數的使用姿式ajax
首先須要搭建一個後端的請求,爲了快速演示spring
利用spring-boot建立了一個機器簡單的工程,依賴版本 1.5.4.RELEASE
後端
get請求參數,通常都是直接掛在請求的url上,因此獲取這些參數仍是比較簡單的spring-mvc
這個能夠說是最基本最多見的的方式了,javax.servlet.ServletRequest#getParameter
來獲取對應的參數,下面各處一個實例mvc
@RestController @RequestMapping(path = "webs/demo") public class DemoController { @RequestMapping(path = "req1") public String req1(HttpServletRequest request) { String user = request.getParameter("user"); String password = request.getParameter("password"); return "req1 user: " + user + " pwd: " + password; } }
根據上面暴露的接口,咱們測試的case就很簡單了app
http://127.0.0.1:8080/webs/demo/req1?user=小灰灰Blog&password=123456 ## 輸出 req1 user: 小灰灰Blog pwd: 123456 http://127.0.0.1:8080/webs/demo/req1?user=小灰灰Blog ## 輸出 req1 user: 小灰灰Blog pwd: null
說明curl
這是一個最基本的獲取參數的方式,get,post請求都適用的,一般在filter,intercepter中也是能夠經過HttpServletRequest
對象來獲取請求參數ide
除了獲取常見的請求參數以外,HttpServletRequest
能夠獲取請求頭的完整信息
在一次請求的生命週期內,能夠經過下面的方式獲取Request對象(固然也能夠獲取response對象)
HttpServletRequest httpServletRequest = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
直接給出case, 這個方法依然是放在上面的DemoController下面的
@RequestMapping(path = "req2") public String req2(String user, String password) { return "req2 user: " + user + " pwd: " + password; }
請求驗證
http://127.0.0.1:8080/webs/demo/req2?user=%E5%B0%8F%E7%81%B0%E7%81%B0Blog&password=123456 ## 輸出: req2 user: 小灰灰Blog pwd: 123456 http://127.0.0.1:8080/webs/demo/req2?password=123456 ## 輸出: req2 user: null pwd: 123456 http://127.0.0.1:8080/webs/demo/req2?password=123456&User=blog ## 輸出: req2 user: null pwd: 123456
注意:
一個疑問
上面的demo中Controller的方法參數都是String還好,若是將password改爲int,會出現什麼狀況
代碼稍做修改
@RequestMapping(path = "req2") public String req2(String user, int password) { return "req2 user: " + user + " pwd: " + password; }
實際測試
# case1 http://127.0.0.1:8080/webs/demo/req2?password=123456&user=blog ## 輸出: req2 user: blog pwd: 123456 # case 2 http://127.0.0.1:8080/webs/demo/req2?password2=123456&user=blog ## 輸出: 報錯, Optional int parameter 'password' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type # case 3 http://127.0.0.1:8080/webs/demo/req2?password=abc&user=blog ## 輸出:報錯, "Failed to convert value of type 'java.lang.String' to required type 'int'; nested exception is java.lang.NumberFormatException: For input string: "abc""
結果說明
經過@RequestParam
註解獲取參數的方式和上面的一種比較相似,case以下
@RequestMapping(path = "req3", method = RequestMethod.GET) public String req3(@RequestParam("user") String username, @RequestParam("password") String pwd) { return "req3 user: " + username + " pwd: " + pwd; }
測試case
# case1 http://127.0.0.1:8080/webs/demo/req3?password=123456&user=blog ## 輸出: req3 user: blog pwd: 123456 # case2 http://127.0.0.1:8080/webs/demo/req3?password=123456 ## 輸出:報錯, Required String parameter 'user' is not presen
說明
@RequestParam(name = "user", required = false) String username
對於請求參數比較複雜的狀況下,我比較喜歡這種使用姿式,管理起來方便簡單
@Data public static class UserDO { String user; String password; } @RequestMapping(path = "req4", method = RequestMethod.GET) public String req4(UserDO userDO) { return "req4 userDO: " + userDO; }
測試case
# case1 http://127.0.0.1:8080/webs/demo/req4?password=123456&user=%E5%B0%8F%E7%81%B0%E7%81%B0Blog ## 輸出: req4 userDO: DemoController.UserDO(user=小灰灰Blog, password=123456) # case2 http://127.0.0.1:8080/webs/demo/req4?password=123456 ## 輸出: req4 userDO: DemoController.UserDO(user=null, password=123456)
說明
@ModelAttribute註解的方法,會優於Controller以前執行,通常更常見於向視圖傳輸數據使用,此處不詳細展開,正常來說,專門的獲取參數不太會用這這種方式來玩
Path參數,專指的是請求路徑的參數,如
http://127.0.0.1:8080/webs/demo/req4?password=123456
上面這個url中,password是咱們傳統意義上的請求參數,其中path參數則是指其中 req4
, demo
這種path路徑中的一環;對此,最多見的一個case就是常見的博客中,如開源中國的一個博客連接
https://my.oschina.net/u/566591/blog/1601400
通常path參數的獲取方式以下
@RequestMapping(path = "req6/{user}/info") public String req6(@PathVariable(name = "user") String user) { return "req6 user: " + user; }
測試case
# case1 http://127.0.0.1:8080/webs/demo/req6/blog/info?user=haha ## 輸出:req6 user: blog # case2 http://127.0.0.1:8080/webs/demo/req6/blog?user=haha ## 輸出: 404 # case3 http://127.0.0.1:8080/webs/demo/req6/info?user=haha ## 輸出: 404
注意:
POST請求參數,更多的是看提交表單參數是否能夠獲取到,以及如何獲取,主要的手段依然是上面幾種方式,下面驗證下是否ok
測試case,能夠藉助curl來實現post請求
# case1 curl -d "user=小灰灰Blog&password=123456" "http://127.0.0.1:8080/webs/demo/req1" ## 輸出: req1 user: 小灰灰Blog pwd: 123456 # case2 curl -d "user=小灰灰Blog" "http://127.0.0.1:8080/webs/demo/req1?password=123456" ## 輸出:req1 user: 小灰灰Blog pwd: 12345 # case3 curl -d "user=小灰灰Blog" "http://127.0.0.1:8080/webs/demo/req1?user=greyBlog" ## 輸出:req1 user: greyBlog pwd: null
curl也能夠換成js請求測試方式
var formData = new FormData(); formData.append("user", "小灰灰Blog"); $.ajax({ url: 'http://127.0.0.1:8080/webs/demo/req1?password=123456', type: 'post', cache: false, data: formData, processData: false, contentType: false });
說明
幾個測試demo以下
# case 1 curl -d "user=小灰灰Blog&password=123456" "http://127.0.0.1:8080/webs/demo/req2" ## 輸出: req2 user: 小灰灰Blog pwd: 123456 # case 2 curl -d "password=123456" "http://127.0.0.1:8080/webs/demo/req2" ## 輸出:req2 user: null pwd: 123456 # case 3 curl -d "password=123456" "http://127.0.0.1:8080/webs/demo/req2?user=blog" ## 輸出: req2 user: blog pwd: 123456
基本上使用姿式和get沒什麼區別
# case 1 curl -d "password=123456&user=blog" "http://127.0.0.1:8080/webs/demo/req3" ## 輸出: req3 user: blog pwd: 123456 # case 2 curl -d "password=123456" "http://127.0.0.1:8080/webs/demo/req3?user=blog" ## 輸出: req3 user: blog pwd: 123456 # case 3 curl -d "password=123456&user=blog" "http://127.0.0.1:8080/webs/demo/req3?password=900" ## 輸出:req3 user: blog pwd: 900,123456
注意
## case1 curl -d "password=123456&user=blog" "http://127.0.0.1:8080/webs/demo/req4?password=900" ## 輸出 req4 userDO: DemoController.UserDO(user=blog, password=900,123456) ## case2 curl -d "password=123456&user=blog" "http://127.0.0.1:8080/webs/demo/req4" ## 輸出 req4 userDO: DemoController.UserDO(user=blog, password=123456) ## case3 curl -d "password=123456" "http://127.0.0.1:8080/webs/demo/req4" ## 輸出 req4 userDO: DemoController.UserDO(user=null, password=123456)
這種方式不區分get,post,因此徹底複雜的交互接口,徹底能夠考慮用bean的方式來定義請求參數
這個無法玩...
上傳文件的支持,對於傳統的spring-mvc來講,可能須要一些添加一些相關配置,不在本文的範疇內,下面默認已經配置好
@RequestMapping(path = {"wx/upload", "wx/wx/upload"}, method = {RequestMethod.GET, RequestMethod.POST, RequestMethod.OPTIONS}) @ResponseBody public String upload(HttpServletRequest request) { MultipartFile file = null; if (request instanceof MultipartHttpServletRequest) { file = ((MultipartHttpServletRequest) request).getFile("image"); } if (file == null) { throw new IllegalArgumentException("圖片不能爲空!"); } return "success"; }
簡單來講,主要是利用HttpServletRequest
來獲取上傳的文件
注意:
MultipartHttpServletRequest
, 此時調用方若是不傳參數,會被異常攔截(能夠經過@ControllerAdvice來攔截全局異常)((MultipartHttpServletRequest) request).getFile(xxx)
來獲取指定名的上傳文件方式 | 注意事項 |
---|---|
HttpServletRequest獲取參數 | 最多見通用 |
方法參數與請求參數同名 | 注意參數名統一,注意類型一致,儘可能不用非包裝基本類型 |
@RequestParam註解 | 同上,可註解內指定http參數名 |
Bean方式 | 定義一個bean,會將同名的http參數賦值進去,推薦 |
@PathVariable 註解 | 請求url參數 |
使用MultipartHttpServletRequest
來獲取上傳的文件,固然也能夠獲取基本的請求參數
盡信書則不如,已上內容,純屬一家之言,因本人能力通常,看法不全,若有問題,歡迎批評指正