@PathVariable、@RequestBody和@RequestParam使用場景及區別


SpringMVC數據綁定接收復雜數據處理方案

常用於數據綁定的幾個注解@PathVariable,@RequestBody@RequestParam,本文配合postman,講解常見的前后台數據交互中的一些數據綁定的問題

@PathVariable

PathVariable是路徑變量的意思,這個注解主要作用在請求URL路徑上的數據綁定,默認傳遞數值寫在URL上,SpringMVC就可以獲取到

  • 支持請求方式:GET
  • 參數傳遞:在URL上直接傳遞
@RequestMapping("/Student")
@RestController
public class DataBindController {
    @Autowired
    private StudentService studentService;
    @GetMapping("/getStudent/{id}")
    public Student getStudentById(@PathVariable Integer id){
        Student student = studentService.getStudentById(id);
        return student;
    }
}

image-20201116112200101

@RequestBody

RequestBody是請求體的意思,這個注解作用在請求體的數據綁定,並且數據必須在寫在請求體中,還要以JSON的數據格式發送才符合條件

該注解常用來處理Content-Type: 不是application/x-www-form-urlencoded編碼的內容,例如application/json, application/xml等;

  • 支持請求方式:GET,POST,PUT,DELETE
  • 參數傳遞:在Body中傳遞
  • 支持的Content-Type:json
    @PostMapping("/addStudent")
    public Student addStudent(@RequestBody Student student){
        System.out.println(student);
        return student;
    }

image-20201116115627710

@RequestParam

RequestParam是請求參數的意思,這個注解的作用在請求路徑和請求體中的數據,因為使用request.getParameter()方式獲取參數

所以可以處理get 方式中queryString的值,也可以處理post方式中 body data的值

  • 支持請求方式:GET,POST,PUT,DELETE
  • 參數傳遞:在Body中傳遞
  • 支持的Content-Type:json

image-20201116132325979

在請求體中的參數必須指定是form-data或者x-www-form-urlencoded,這兩種方式是以表單的形式提交數據,使用這兩種方式

會將表單內的數據轉換為鍵值對,&分隔形式封裝在請求體中傳送給后台,前者和后者的區別是在於對非ASCII碼字符的轉碼,

前者是直接發送,后者是轉碼成百分號發送

image-20201116132756739

三個注解小結

注解 請求參數位置 請求方式 支持的Content-Type 請求示例
@PathVariable Url Get Get請求沒有Content-Type /students/1
@RequestParam Url和Body Get/Post/Put/Delete/Patch form-data,x-www-form-urlencoded /students?name=zs&age=23
@RequestBody Body Post/Put/Delete/Patch application/json {"id":1,"name":"zs","age":23}

三個注解的源碼和使用場景:

@PathVariable

這個注解我一般在工作中,會用在單個對象的查詢上,比如要根據ID值查詢學生信息,就會在Postman發送GET請求,后台使用@PathVariable接收

  • 優點:適合接收簡單類型的數據綁定,如int,string這兩個常用
  • 缺點:id暴露在url上,對於不方便泄露ID的值請求,最好不要使用。只支持Get方式,請求方式有局限性,不支持復雜數據類型,自定義數據類型

源碼

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
    /**
     * 參數名稱
     */
    String value() default "";
}

源碼解析

  • @PathVariable注解源碼中只有一個參數,不填的默認是綁定到與路徑參數同名的形參變量

  • 如果要接收多個路徑變量,則需要聲明多個@PathVariable變量

  @RequestMapping("/Student/{name}/{age}")
  public Object getStudentInfo (@PathVariable String name,@PathVariable Integer age){
      //...
  }

使用解析

  • POSTMAN發送的鏈接:http://localhost:8080/Student/getStudent/1
  • 后端接收參數:/Student/getStudent/{id},這里的id是路徑上的參數,傳什么值接收什么值
  • 后端映射值:@PathVariable Integer id 這里的方法參數id要與路徑變量參數id同名,因為@PathVariable沒有指定別名的注解變量

@RequestParam

這個注解我一般在工作中,會用在組合查詢多個對象,比如跟據姓名模糊查詢和性別組合查詢篩選學生,就會發送POST請求,后台使用RequestParam接收

  • 優點:支持常用多種請求方式,請求參數可以封裝在請求體中較為安全
  • 缺點:id暴露在url上,對於不方便泄露ID的值請求,最好不要使用。只支持Get方式,請求方式有局限性

源碼

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
 
    /**
     * 參數名稱(和value同等意思)
     */
    @AliasFor("name")
    String value() default "";
 
    /**
     * 參數名稱 (和name同等意思)
     */
    @AliasFor("value")
    String name() default "";
 
    /**
     * 是否必選(默認必選)
     */
    boolean required() default true;
 
    /**
     * 參數默認值
     */
    String defaultValue() default ValueConstants.DEFAULT_NONE;
 
}

源碼解析

@RequestParam總體上來說,該注解類擁有三個參數:

  • value、name 屬性都標識請求參數名(必須配置)

  • required:參數是否必傳,默認為 true,可以設置為非必傳 false;(如果設置了必傳或默認,請求未傳遞參數,將會拋出異常)

  • defaultValue:參數默認值,如果設置了該值,required 將會自動設置為 false

使用解析

  • get請求的 requestHeaders 中 content-type 這個字段,使用 form-data 表單形式攜帶參數請求

  • Spring中的@RequestParam注解接收的參數大多數場景是來自Request Headers中,

  • 即請求頭,也就是url中,格式為:http://localhost:8080?name=zs&age=23,由於 url 長度有限制,所以參數需要限制數量和值得長度

@RequestBody

源碼

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {
 
    /**
     * 默認參數必傳
     */
    boolean required() default true;
 
}

源碼解析

  • @RequestBody注解只擁有一個參數
  • required 默認為 true,即對象中的屬性必須有一個要傳,否則會拋出異常

使用解析

  • post請求的requestHeaders請求頭中有content-type字段,一般用來處理:applicatin/json格式的參數;

  • Spring中的@RequestBody注解是用來接收請求體中的參數數據,即requestBody請求體中,故不受參數數據長度的限制;

補充HTTP知識:Post、Get、Put、Delete

Http協議常用的四種請求方式:Post、Get、Put、Delete等;其中Put、Delete請求方式很少見,都可用Post方式代替!

  • 對數據庫而言: get 請求不修改數據庫,只是查詢。Post是增加記錄,put是更新,Delete數據庫刪除;
  • Put,Post,Delete 方式的請求參數會直接放在requestBody里;
  • 處理 request uri 部分的注解,路徑參數變量:@PathVariable;
  • 處理request header部分的注解: @RequestHeader, @CookieValue,@RequestParam;
  • 處理request body部分的注解:@RequestParam, @RequestBody;  
  • 綜上所述:@RequestParam注解既可以接收Get方式的請求頭中的參數,也可以接收Post方式的請求體中的參數;

補充HTTP知識: Content-Type與Accept

--------Response Headers-----------
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
If-Modified-Since: 0
expire: 0
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Tue, 17 Nov 2020 05:48:54 GMT

--------Request Headers-----------
POST /student/update HTTP/1.1
Host: localhost:9002
Connection: keep-alive
Content-Length: 21
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json
X-Requested-With: XMLHttpRequest
User-Agent: Chrome/86.0.4240.75 Mobile Safari/537.36
Content-Type: application/json

Accept

Accept代表發送希望接受的數據類型

比如:Accept:application/json;

比如我們用瀏覽器發送請求中,請求頭Request Headers帶有Accept:application/json; ,

那就是表明瀏覽器發送這個請求,希望服務器傳送回的數據格式是json數據格式

Content-Type

Content-Type代表發送端發送的數據類型

比如:Content-Type:application/json;

Response Headers帶有Content-Type: application/json就代表服務器希發送數據類型是json類型

Request Headers帶有Content-Type: application/json就代表服務器希發送數據類型是json類型

上述報文解釋

瀏覽器發送了POST請求,這次請求發送的數據格式是JSON數據給是,希望服務器能返回JSON的數據格式

服務器發送返回了JSON形式的數據格式數據給瀏覽器

常見Content-Type媒體類型

Get請求的 headers 中沒有 content-type 這個字段,Put、Delete和Post 請求的headers 是有 content-type 這個字段的

常見Content-Type媒體類型如下:

  • application/x-www-form-urlencoded 這種就是一般的文本表單用 post 傳地數據,

    只要將得到的 data 用 @RequestParam 或 request.getParamter() 獲取即可;

  • multipart/form-data ,用於文件上傳,此時 form 的 enctype 屬性必須指定為 multipart/form-data;

  • application/json,將數據以json對象的格式傳遞;

  • text/xml;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM