SpringMVC獲得請求引數值的幾種方法
阿新 • • 發佈:2018-12-04
有不少同事在工作過程中,會遇到分不清如何獲得請求引數值的情況,明明自己測試過的介面是可以獲得引數的值的,而給第三方呼叫的時候就不可以,這些情況不甚列舉。下面博主就給大家詳細介紹SpringMVC獲得請求引數獲取的幾種方法。
首先介紹幾種常見的Request請求方式
首先介紹幾種常見的Request請求方式,以PostMan發起請求為例
- get方法:最為簡單,既將引數新增到請求URL當中,如:http://localhost:8080/demo/web/getrequestvalue/addUserByBeanUseRequestBody?age=10&name=yun
- post(Content-Type: application/x-www-form-urlencoded):瀏覽器的原生 form 表單,如果不設定 enctype 屬性,那麼最終就會以 application/x-www-form-urlencoded 方式提交資料。請求類似於下面這樣(略掉無關的請求頭):
POST http://www.example.com HTTP/1.1 Content-Type: application/x-www-form-urlencoded;charset=utf-8 title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
- post(Content-Type: multipart/form-data):使用表單上傳檔案時,必須讓 form 的 enctyped 等於這個值。用於上傳檔案與KeyValue共同存在的請求。
- post(Content-Type: application/json):現在越來越多的人把它作為請求頭,用來告訴服務端訊息主體是序列化後的 JSON 字串。使用最為廣泛。
通過HttpServletRequest接收
最原始的方法,在業務程式碼開發中,不推薦使用,無法到達高效開發的目的。
/** * 最原始的方法,在業務程式碼開發中,不推薦使用,無法到達高效開發的目的:</br> * 通過HttpServletRequest接收: * get方式可以獲得引數的值 * post方式(Content-Type: application/x-www-form-urlencoded)可以獲得引數的值 * post方式(Content-Type: multipart/form-data)可以獲得引數的值 * post方式(Content-Type: application/json)無法獲得引數的值 */ @RequestMapping("/addUserByServletRequest") public ApiResponse addUserByServletRequest(HttpServletRequest request){ User user = new User(); user.setName(request.getParameter("name")); user.setAge(Integer.parseInt(request.getParameter("age"))); log.debug(logSintring+user); return new ApiResponse.ApiResponseBuilder().data(user).build(); }
將請求Key作為介面入參方式
/**
* 將請求Key作為介面入參方式,也是較為傳統的方法,無法到達高效開發的目的:</br>
* get方式可以獲得引數的值
* post方式(Content-Type: application/x-www-form-urlencoded)可以獲得引數的值
* post方式(Content-Type: multipart/form-data)可以獲得引數的值
* post方式(Content-Type: application/json)無法獲得引數的值,報錯:"Optional int parameter '**' 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."
*/
@RequestMapping("/addUserByKeyByKey")
public ApiResponse addUserByKeyByKey(String name, int age){
User user = new User();
user.setName(name);
user.setAge(age);
log.debug(logSintring+user);
return new ApiResponse.ApiResponseBuilder().data(user).build();
}
通過POJOBean作為RestApi介面的入參
/**
* 通過POJOBean作為RestApi介面的入參(SpringMVC做對映),此種方式在實際業務開發中較為實用:</br>
* get方式可以獲得引數的值
* post方式(Content-Type: application/x-www-form-urlencoded)可以獲得引數的值
* post方式(Content-Type: multipart/form-data)可以獲得引數的值
* post方式(Content-Type: application/json)無法獲得引數的值。這種方式必須使用@RequestBody註解在入參當中。
*/
@RequestMapping("/addUserByBean")
public ApiResponse addUserByBean(User user){
log.debug(logSintring+user);
return new ApiResponse.ApiResponseBuilder().data(user).build();
}
通過POJOBean前面加@RequestBody註解作為RestApi介面的入參
/**
* 通過POJOBean前面加@RequestBody註解作為RestApi介面的入參(SpringMVC做對映),此種方式在實際業務開發中較為實用,配合研發規範,可以達到較高效開發效率:</br>
* get方式不支援,報錯:Required request body is missing:
* post方式(Content-Type: application/x-www-form-urlencoded)不可以,報錯:Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
* post方式(Content-Type: multipart/form-data)不可以,報錯:Content type 'multipart/form-data;boundary=----WebKitFormBoundaryQQDXKavdsLyPAphR;charset=UTF-8' not supported
* post方式(Content-Type: application/json)可以獲得引數的值
*/
@RequestMapping("/addUserByBeanUseRequestBody")
public ApiResponse addUserByBeanUseRequestBody(@RequestBody User user){
log.debug(logSintring+user.toString());
return new ApiResponse.ApiResponseBuilder().data(user).build();
}
通過@PathVariable註解獲得請求URL中的引數值
/**
* 通過@PathVariable註解獲得請求URL中的引數值,此種方式在實際業務開發中較為少見,此種情況符合Restful規範,但是使用不是很方便,尤其是在做介面自動化測試的時候,資料加密也比較困難,建議較少使用:</br>
* get方式支援,需要請求URL路徑中有這些資訊
* post方式:不管是哪種方式都不支援。 如果post請求的URL路徑符合PathVariable也是規則,也是可以獲得引數的
*/
@RequestMapping("/addUserByPathValue/{useName}/{userAge}")
public ApiResponse addUserByPathValue(@PathVariable String useName, @PathVariable("userAge") int age){
User user = new User();
user.setAge(age);
user.setName(useName);
log.debug(logSintring+user);
return new ApiResponse.ApiResponseBuilder().data(user).build();
}
通過@RequestParam註解獲得請引數值
/**
* 通過@RequestParam註解獲得請引數值,此種方式在實際業務開發中使用較多,此種情況符合Restful規範,但是使用不是很方便,尤其是在做介面自動化測試的時候,資料加密也比較困難,建議較少使用:</br>
* get方式支援,需要請求URL路徑中有這些資訊
* post方式(Content-Type: application/x-www-form-urlencoded)可以。 但是 required = false, defaultValue = "99" 不起作用,即age必須要有此請求引數
* post方式(Content-Type: multipart/form-data) 可以。 但是 required = false, defaultValue = "99" 不起作用,即age必須要有此請求引數
* post方式(Content-Type: application/json) 不可以。
*/
@RequestMapping("/addUserByRequestParam")
public ApiResponse addUserByRequestParam(@RequestParam("name") String userName,
@RequestParam(value = "age", required = false, defaultValue = "99") int userAge){
User user = new User(userName,userAge);
log.debug(logSintring+user);
return new ApiResponse.ApiResponseBuilder().data(user).build();
}
最佳實踐
如上有這麼多獲得請求引數值的方法,那麼在實際工作中,哪些最建議使用呢。 現在大家的開發模式都是前後端分離開發,所以使用“post方式(Content-Type: application/json)”作為Ajax最為常見,故Spring端使用“@RequestBody Bean”獲得請求引數值最為方便高效,使用頻率也最高。用此方式再配合"hibernate validate"工具,可以很方便的做引數校驗工作。 在一個人數較多的研發團隊中,使用此規範(雖然很多時間不符合Restful風格),可以讓團隊產生很高的研發效率,此種規範產生的介面文件,在給測試人員做介面自動化測試工作中,也會帶來很大的便捷性,不然不同的請求風格、不同的請求型別與或者引數的方法,將大大降低測試人員做介面自動化指令碼編寫的速度。本博文的示例程式碼見GitHub《https://github.com/yun19830206/JavaTechnicalSummary/blob/master/Rd_Standard/src/main/java/com/cloud/rdstandard/web/GetHttpRequestParamValueDemo.java》