SpringMVC獲得請求參數值的幾種方法

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章