@RequestParam、@RequestBody、@ResponseBody和@PathVariable的使用與區別

目錄

一、@RequestParam 註解

1.1 解釋說明

1.2 代碼示例

1.3 總結

二、@RequestBody 註解

2.1 解釋說明

2.2 代碼示例

2.3 總結

三、@ResponseBody 註解

3.1 解釋說明

3.2 代碼示例

3.3 總結

四、@PathVariable 註解

4.1 解釋說明

4.2 代碼示例

4.3 總結


一、@RequestParam 註解

1.1 解釋說明

@RequestParam用來處理Content-Type: 爲 application/x-www-form-urlencoded編碼的內容。(Http協議中,如果不指定Content-Type,則默認傳遞的參數就是application/x-www-form-urlencoded類型)

@RequestParam可以接受簡單類型的屬性,也可以接受對象類型。(實質是將Request.getParameter() 中的Key-Value參數Map利用Spring的轉化機制ConversionService配置,轉化成參數接收對象或字段。)

知識點:在Content-Type: application/x-www-form-urlencoded的請求中,get 方式中queryString的值,和post方式中body data 的值都會被Servlet接受到並轉化到Request.getParameter()參數集中,所以@RequestParam可以獲取的到。

1.2 代碼示例

GET和POST請求傳的參數會自動轉換賦值到@RequestParam 所註解的變量上

@RequestParam(org.springframework.web.bind.annotation.RequestParam)用於將指定的請求參數賦值給方法中的形參。

<form action="/user/requestParamTest" method="get">
    requestParam Test<br>
    用戶名字:<input type="text" name="username"><br>
    用戶暱稱:<input type="text" name="nickname"><br>
    <input type="submit" value="提交">
</form>
@RequestMapping(value="/requestParamTest", method = RequestMethod.GET)
public String requestParamTest(@RequestParam(value="username") String userName, @RequestParam(value="nickname") String nickName){
    System.out.println("requestParam Test");
    System.out.println("username: " + userName);
    System.out.println("nickname: " + nickName);
    return "hello";
}


上述代碼會將請求中的username參數的值賦給username變量。請求中的參數username和nickname必須與@RequestParam(value="xxxx")的value值保持一致。

等價於:

@RequestMapping(value="/requestParamTest", method = RequestMethod.GET)
public String requestParamTest(HttpServletRequest request){
    System.out.println("requestParam Test");
    String username = request.getParameter("username");
    System.out.println("username: " + username);
    String nickname = request.getParameter("nickname");
    System.out.println("nickname: " + nickname);
    return "hello";
}

也可以不使用@RequestParam,直接接收,此時要求controller方法中的參數名稱要跟form中name名稱一致

@RequestMapping(value="/requestParamTest", method = RequestMethod.GET)
public String requestParamTest(String username, String nickname){
    System.out.println("requestParam Test");
    System.out.println("username: " + username);
    System.out.println("nickname: " + nickname);
    return "hello";
}

1.3 總結

接收請求參數的方式:

方式一:用@RequestParam接受。(@RequestParam(value="username") String userName, @RequestParam(value="nickname") String nickName) //value中的參數名稱要跟請求參數Key的名稱一致
方式二:不用註解,直接接受。(String username, String nickname) // 此時要參數名稱一致
方式三:用HttpServletRequest接受。(HttpServletRequest request) //request.getParameter("username")

二、@RequestBody 註解

2.1 解釋說明

@RequestBody 註解則是將 HTTP 請求正文插入方法中,使用適合的 HttpMessageConverter 將請求體寫入某個對象。

作用:

1) 該註解用於讀取Request請求的body部分數據,使用系統默認配置的HttpMessageConverter進行解析,然後把相應的數據綁定到要返回的對象上;
2) 再把HttpMessageConverter返回的對象數據綁定到 controller中方法的參數上。

@RequestBody註解可以接收json格式的數據,並將其轉換成對應的數據類型。

@RequestBody處理HttpEntity傳遞過來的數據,一般用來處理非Content-Type: application/x-www-form-urlencoded編碼格式的數據。

GET請求中,因爲沒有HttpEntity,所以@RequestBody並不適用。
POST請求中,通過HttpEntity傳遞的參數,必須要在請求頭中聲明數據的類型Content-Type,SpringMVC通過使用HandlerAdapter 配置的HttpMessageConverters來解析HttpEntity中的數據,然後綁定到相應的實體bean上。

2.2 代碼示例

@RequestBody接收一個對象

@ApiOperation("外設SDK按照參數查詢可展示的廣告信息")
@PostMapping("/openapi/advert/getOutAdvertList")
public CommResponse<?> getOutAdvertList(@RequestBody OutAdvertRequestParam outAdvertRequestParam);

(1)前臺界面,這裏以小程序爲例

wx.request({
      url: host.host + `/WxProgram/deleteBookById`,
      method: 'POST',
      data: {
        nick: this.data.userInfo.nickName,
        bookIds: bookIds
      },
      success: (res) => {
        console.log(res);
        this.getCollectionListFn();
      },
      fail: (err) => {
        console.log(err);
      }
    })

(2)controller層

@RequestMapping(value="/deleteBookById",method=RequestMethod.POST)
@ResponseBody
public void deleteBookById(@RequestBody Map<String, String> map){
    String bookIds = map.get("bookIds");
    String nick = map.get("nick");
    String[] idArray = bookIds.split(",");
    Integer userId = wxService.findIdByNick(nick);
    for(String id : idArray){
        Integer bookid = Integer.parseInt(id);
        System.out.println("bookid: " + bookid);
        wxService.removeBookById(bookid, userId);
    }
}

2.3 總結

在GET請求中,不能使用@RequestBody
在POST請求,可以使用@RequestBody@RequestParam,但是如果使用@RequestBody,對於參數轉化的配置必須統一。
舉個例子,在SpringMVC配置了HttpMessageConverters處理棧中,指定json轉化的格式,如Date轉成‘yyyy-MM-dd’,則參數接收對象包含的字段如果是Date類型,就只能讓客戶端傳遞年月日的格式,不能傳時分秒。因爲不同的接口,它的參數可能對時間參數有不同的格式要求,所以這樣做會讓客戶端調用同事對參數的格式有點困惑,所以說擴展性不高。

如果使用@RequestParam來接受參數,可以在接受參數的model中設置@DateFormat指定所需要接受時間參數的格式。

另外,使用@RequestBody接受的參數是不會被Servlet轉化統一放在request對象的Param參數集中,@RequestParam是可以的。

綜上所述,一般情況下,推薦使用@RequestParam註解來接受Http請求參數。


三、@ResponseBody 註解

3.1 解釋說明

@Responsebody 註解表示該方法的返回的結果直接寫入 HTTP 響應正文(ResponseBody)中,一般在異步獲取數據時使用,通常是在使用 @RequestMapping 後,返回值通常解析爲跳轉路徑,加上 @Responsebody 後返回結果不會被解析爲跳轉路徑,而是直接寫入HTTP 響應正文中。
作用:
該註解用於將Controller的方法返回的對象,通過適當的HttpMessageConverter轉換爲指定格式後,寫入到Response對象的body數據區。
使用時機:
返回的數據不是html標籤的頁面,而是其他某種格式的數據時(如json、xml等)使用;

3.2 代碼示例

當頁面發出異步請求:

function login() {
    var datas = '{"username":"' + $('#username').val() + '","userid":"' + $('#userid').val() + '","status":"' + $('#status').val() + '"}';
    $.ajax({
        type : 'POST',
        contentType : 'application/json',
        url : "${pageContext.request.contextPath}/user/login",
        processData : false,
        dataType : 'json',
        data : datas,
        success : function(data) {
            alert("userid: " + data.userid + "username: " + data.username + "status: "+ data.status);
        },
        error : function(XMLHttpRequest, textStatus, errorThrown) {
            alert("出現異常,異常信息:"+textStatus,"error");
        }
    });
};
@RequestMapping(value = "user/login")
@ResponseBody
// 將ajax(datas)發出的請求寫入 User 對象中,返回json對象響應回去
public User login(User user) {   
    User user = new User();
    user .setUserid(1);
    user .setUsername("MrF");
    user .setStatus("1");
    return user ;
}

異步獲取 json 數據,加上 @Responsebody 註解後,就會直接返回 json 數據。

3.3 總結

當前端頁面需要返回 json 數據時,可以使用@ResponseBody加到方法上。

四、@PathVariable 註解

4.1 解釋說明

@PathVariable 註解,其用來獲取請求路徑(url )中的動態參數。

在默認的情況下,Spring會對@PathVariable註解的變量進行自動賦值,當然你也可以指定@PathVariable使用哪一個URL中的變量。

4.2 代碼示例

(1)頁面發出請求:

function login() {
    var url = "${pageContext.request.contextPath}/person/login/";
    var query = $('#id').val() + '/' + $('#name').val() + '/' + $('#status').val();
    url += query;
    $.get(url, function(data) {
        alert("id: " + data.id + "name: " + data.name + "status: "
                + data.status);
    });
}

(2)Controller層

/**
* @RequestMapping(value = "user/login/{id}/{name}/{status}") 中的 {id}/{name}/{status}
* 與 @PathVariable int id、@PathVariable String name、@PathVariable boolean status
* 一一對應,按名匹配。
*/
@RequestMapping(value = "user/login/{id}/{name}/{status}")
@ResponseBody
//@PathVariable註解下的數據類型均可用
public User login(@PathVariable int id, @PathVariable String name, @PathVariable boolean status) {
//返回一個User對象響應ajax的請求
    return new User(id, name, status);
}

這種情況下,Spring能夠根據名字自動賦值對應的函數參數值,當然也可以在@PathVariable中顯示地表明具體的URL變量值。

在默認情況下,@PathVariable註解的參數可以是一些基本的簡單類型:int,long,Date,String等,Spring能根據URL變量的具體值以及函數參數的類型來進行轉換。

(3) 匹配正則表達式

很多時候,需要對URL變量進行更加精確的定義,例如-用戶名只可能包含小寫字母,數字,下劃線,我們希望:

/user/fpc是一個合法的URL
/user/#$$$則不是一個合法的URL

除了簡單地定義{username}變量,還可以定義正則表達式進行更精確的控制,定義語法是{變量名:正則表達式}[a-zA-Z0-9_]+是一個正則表達式,表示只能包含小寫字母,大寫字母,數字,下劃線。如此設置URL變量規則後,不合法的URL則不會被處理,直接由SpringMVC框架返回404Not Found。

@RequestMapping("/user/{username:[a-zA-Z0-9_]+}/blog/{blogId}")

4.3 總結

(1) 在@RequestMapping註解中定義URL變量規則;
(2) 在@RequestMapping註解方法中獲取URL變量-@PathVariable;
(3) @PathVariable指定URL變量名;
(4) 定義多個URL變量;
(5) 用正則表達式精確定義URL變量;

 

【參考資料】
1、可參考SpringBoot-@PathVariable:https://www.cnblogs.com/williamjie/p/9139548.html

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