@RequestParam、@RequestBody和@ModelAttribute區別

一、@RequestParam
GET和POST請求傳的參數會自動轉換賦值到@RequestParam 所註解的變量上
1. @RequestParam(org.springframework.web.bind.annotation.RequestParam)用於將指定的請求參數賦值給方法中的形參。
例:
(1) get請求:

url請求:http://localhost:8080/WxProgram/findAllBookByTag?tagId=1&pageIndex=3

userTest.jsp

<form action="/WxProgram/json/requestParamTest" method="get">
    requestParam Test<br>
    用戶名:<input type="text" name="username"><br>
    用戶暱稱:<input type="text" name="usernick"><br>
    <input type="submit" value="提交">
</form>

UserController.java

複製代碼

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

複製代碼

上述代碼會將請求中的username參數的值賦給username變量。

等價於:

複製代碼

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

複製代碼

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

複製代碼

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

複製代碼

總結:

接收請求參數的方式:

@RequestParam(value="username") String userName, @RequestParam(value="usernick") String userNick //value中的參數名稱要跟name中參數名稱一致
String username, String usernick// 此時要參數名稱一致
HttpServletRequest request //request.getParameter("usernick")

(2) post請求:
跟get請求格式一樣,只是把方法中的get換成post

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

RequestParam實質是將Request.getParameter() 中的Key-Value參數Map利用Spring的轉化機制ConversionService配置,轉化成參數接收對象或字段。

get方式中query String的值,和post方式中body data的值都會被Servlet接受到並轉化到Request.getParameter()參數集中,所以@RequestParam可以獲取的到。

二. @RequestBody

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

1. @RequestBody接收一個對象
url請求:http://localhost:8080/WxProgram/findBookByName

複製代碼

@RequestMapping(value="/findBookByName", method = RequestMethod.POST)
@ResponseBody
public DbBook findBookByName(@RequestBody DbBook book){
    System.out.println("book: " + book.toString());
    System.out.println("book name: " + book.getTitle());
    String bookName = book.getTitle();
    DbBook book = wxService.findBookByName(bookName);    
    return book;
}

複製代碼

2. @RequestBody接收不同的字符串

(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);
    }
}

複製代碼

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

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

@RequestBody用於post請求,不能用於get請求

這裏涉及到使用@RequestBody接收不同的對象
1. 創建一個新的entity,將兩個entity都進去。這是最簡單的,但是不夠“優雅”。
2. 用Map<String, Object>接受request body,自己反序列化到各個entity中。
3. 類似方法2,不過更爲generic,實現自己的HandlerMethodArgumentResolver。參考這裏 

三、@ModelAttribute

@ModelAttribute註解類型將參數綁定到Model對象

1. userTest.jsp

複製代碼

<form action="/WxProgram/json/modelAttributeTest" method="post">
    modelAttribute Test<br>
    用戶id:<input type="text" name="userId"><br>
    用戶名:<input type="text" name="userName"><br>
    用戶密碼:<input type="password" name="userPwd"><br>
    <input type="submit" value="提交"><br>
</form>

複製代碼

name的屬性值要跟User的屬性相對應。

2. UserController.java

複製代碼

@RequestMapping(value="/modelAttributeTest", method = RequestMethod.POST)
    public String modelAttributeTest(@ModelAttribute User user){
        System.out.println("modelAttribute Test");
        System.out.println("userid: " + user.getUserId());
        System.out.println("username: " + user.getUserName());
        System.out.println("userpwd: " + user.getUserPwd());
        return "hello";
    }

複製代碼

3. User.java

複製代碼

public class User {
    private Integer userId;
    private String userName;
    private String userPwd;
    
    public User(){
        super();
    }
        //setter and getter      
}

複製代碼

 

當前臺界面使用GET或POST方式提交數據時,數據編碼格式由請求頭的ContentType指定。分爲以下幾種情況:
1. application/x-www-form-urlencoded,這種情況的數據@RequestParam、@ModelAttribute可以處理,@RequestBody也可以處理。
2. multipart/form-data,@RequestBody不能處理這種格式的數據。(form表單裏面有文件上傳時,必須要指定enctype屬性值爲multipart/form-data,意思是以二進制流的形式傳輸文件。)
3. application/json、application/xml等格式的數據,必須使用@RequestBody來處理。

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