有不少同事在工作過程中,會遇到分不清如何獲得請求參數值的情況,明明自己測試過的接口是可以獲得參數的值的,而給第三方調用的時候就不可以,這些情況不甚枚舉。下面博主就給大家詳細介紹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》