最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot中接口傳參的三大注解(RequestParam/RequestBody/PathVariable)全面解析

 更新時(shí)間:2026年06月25日 08:56:07   作者:花生了什么事o  
本文介紹了?@RequestParam、@PathVariable、@RequestBody三種注解的數(shù)據(jù)來(lái)源和適用場(chǎng)景,并以?HTTP語(yǔ)義為主線,幫助讀者理解不同請(qǐng)求方法下該如何選擇參數(shù)接收方式

我們?cè)趯W(xué)習(xí)后端開(kāi)發(fā)的時(shí)候,都在相應(yīng)教學(xué)內(nèi)容上看到過(guò)這三個(gè)注解。教程里直接給使用方式,但卻沒(méi)有詳細(xì)說(shuō)什么時(shí)候該用哪個(gè)。等到真正寫項(xiàng)目接口的時(shí)候,就會(huì)開(kāi)始糾結(jié):分頁(yè)參數(shù)用 @RequestParam,那查詳情的 ID 放在路徑里用 @PathVariable 還是也用 @RequestParam?提交表單十幾個(gè)字段,是全用 @RequestParam 一個(gè)個(gè)接,還是塞進(jìn)一個(gè)對(duì)象用 @RequestBody?

三種注解都能拿到前端傳來(lái)的數(shù)據(jù),但它們的數(shù)據(jù)來(lái)源、適用場(chǎng)景、HTTP 語(yǔ)義完全不同。搞混了代碼能跑,但接口設(shè)計(jì)會(huì)很別扭。我們一個(gè)一個(gè)來(lái)看一下使用場(chǎng)景。

一、@RequestParam:從 URL 查詢參數(shù)中取值

@RequestParam 對(duì)應(yīng)的是 URL 中 ? 后面的查詢參數(shù)(Query String)。

@GetMapping("/users")
public List<User> listUsers(
        @RequestParam(defaultValue = "1") int page,
        @RequestParam(defaultValue = "10") int size) {
    return userService.listUsers(page, size);
}

前端請(qǐng)求:GET /users?page=1&size=10

Spring 看到 @RequestParam,就知道去 URL 的查詢參數(shù)里找 pagesize 這兩個(gè) key,取出來(lái)轉(zhuǎn)成 int,注入到方法參數(shù)里。defaultValue 是個(gè)保底:如果前端沒(méi)傳這個(gè)參數(shù),就用默認(rèn)值,不會(huì)報(bào)錯(cuò)。

適用場(chǎng)景

篩選、排序、分頁(yè)這種可選的查詢條件。@RequestParam 最合適。參數(shù)是 URL 的一部分,瀏覽器地址欄能直接看到,方便調(diào)試和分享鏈接。

@GetMapping("/products")
public List<Product> search(
        @RequestParam(required = false) String keyword,
        @RequestParam(required = false) String category,
        @RequestParam(defaultValue = "price") String sortBy) {
    return productService.search(keyword, category, sortBy);
}

請(qǐng)求:GET /products?keyword=手機(jī)&category=electronics&sortBy=price

注意 required = false:這個(gè)參數(shù)是可選的,不傳也不會(huì)報(bào) 400。如果你確定某個(gè)參數(shù)必須傳(比如分頁(yè)的頁(yè)碼),可以用 required = true(默認(rèn)值),前端不傳就直接返回 400 錯(cuò)誤。

多個(gè)值的情況

一個(gè)參數(shù)還能接收多個(gè)值,前端用同一個(gè) key 傳多次:

@GetMapping("/users/batch")
public List<User> getByIds(@RequestParam List<Long> ids) {
    return userService.getByIds(ids);
}

請(qǐng)求:GET /users/batch?ids=1,2,3GET /users/batch?ids=1&ids=2&ids=3

Spring 會(huì)自動(dòng)把多個(gè)值收集到 List 里。

二、@PathVariable:從 URL 路徑中取值

@PathVariable 對(duì)應(yīng)的是 URL 路徑中用 {xxx} 占位的部分。

@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
    return userService.getUserById(id);
}

前端請(qǐng)求:GET /users/42

{id} 是一個(gè)路徑變量,@PathVariable 告訴 Spring:去 URL 路徑里把 {id} 位置的值取出來(lái),轉(zhuǎn)成 Long,賦給 id 參數(shù)。

適用場(chǎng)景

標(biāo)識(shí)具體資源的場(chǎng)景。 RESTful 風(fēng)格的 API 設(shè)計(jì)中,用路徑來(lái)表達(dá)"操作的是哪個(gè)資源"。

GET    /users/42          → 查看用戶 42
PUT    /users/42          → 更新用戶 42
DELETE /users/42          → 刪除用戶 42
GET    /orders/1001/items → 查看訂單 1001 的商品列表

路徑中的 42、1001 就是資源標(biāo)識(shí),用 @PathVariable 接收。這種設(shè)計(jì)比 GET /users?id=42 更符合 REST 語(yǔ)義,URL 也更簡(jiǎn)潔直觀。

多個(gè)路徑變量

一個(gè) URL 里可以有多個(gè)占位符:

@GetMapping("/departments/{deptId}/employees/{empId}")
public Employee getEmployee(
        @PathVariable Long deptId,
        @PathVariable Long empId) {
    return employeeService.get(deptId, empId);
}

請(qǐng)求:GET /departments/5/employees/128

兩個(gè)占位符對(duì)應(yīng)兩個(gè) @PathVariable,Spring 會(huì)按名稱匹配。

三、@RequestBody:從請(qǐng)求體中取值

@RequestBody 對(duì)應(yīng)的是 HTTP 請(qǐng)求的 Body 部分。當(dāng)前端發(fā)送 JSON 格式的數(shù)據(jù)時(shí),Spring 會(huì)用 HttpMessageConverter(默認(rèn)是 Jackson)把 JSON 反序列化成 Java 對(duì)象。

@PostMapping("/users")
public User createUser(@RequestBody UserCreateRequest request) {
    return userService.createUser(request);
}
// 請(qǐng)求體對(duì)應(yīng)的 DTO
public class UserCreateRequest {
    private String name;
    private String email;
    private Integer age;
    // getter/setter
}

前端請(qǐng)求:

POST /users
Content-Type: application/json

{
    "name": "張三",
    "email": "zhangsan@example.com",
    "age": 25
}

Spring 看到 @RequestBody,就知道把整個(gè)請(qǐng)求體讀出來(lái),用 Jackson 解析成 UserCreateRequest 對(duì)象。字段名要和 JSON 的 key 對(duì)應(yīng),類型要能轉(zhuǎn)換,否則直接報(bào) 400。

適用場(chǎng)景

提交復(fù)雜表單數(shù)據(jù)、創(chuàng)建或更新資源。 當(dāng)參數(shù)多、結(jié)構(gòu)復(fù)雜、或者包含嵌套對(duì)象時(shí),@RequestBody 是最佳選擇。

// 嵌套對(duì)象的場(chǎng)景
public class OrderCreateRequest {
    private Long userId;
    private List<OrderItem> items;
    private Address shippingAddress;
    private String paymentMethod;
}

public class OrderItem {
    private Long productId;
    private Integer quantity;
}

public class Address {
    private String province;
    private String city;
    private String detail;
}

這種嵌套結(jié)構(gòu),用 @RequestParam 一個(gè)個(gè)接幾乎不可能,用 @RequestBody 一行搞定。

三種注解對(duì)比

對(duì)比維度@RequestParam@PathVariable@RequestBody
數(shù)據(jù)來(lái)源URL 查詢參數(shù) ?key=valueURL 路徑 /users/{id}HTTP 請(qǐng)求體 Body
Content-Type無(wú)要求無(wú)要求通常 application/json
參數(shù)數(shù)量適合少量可選參數(shù)適合 1-2 個(gè)資源標(biāo)識(shí)適合復(fù)雜/大量參數(shù)
HTTP 方法任意任意通常 POST/PUT
典型場(chǎng)景分頁(yè)、篩選、排序資源標(biāo)識(shí)、RESTful 路徑創(chuàng)建、更新、復(fù)雜提交
瀏覽器可見(jiàn)性地址欄可見(jiàn)地址欄可見(jiàn)不可見(jiàn)(在請(qǐng)求體里)

一句話總結(jié):@RequestParam 管查詢條件,@PathVariable 管資源標(biāo)識(shí),@RequestBody 管請(qǐng)求體。

什么時(shí)候用哪個(gè):按 HTTP 語(yǔ)義來(lái)選

與其記住注解的語(yǔ)法,不如理解 HTTP 本身的語(yǔ)義。每個(gè) HTTP 方法有它自己的含義,參數(shù)怎么傳跟著語(yǔ)義走就行了。

GET 請(qǐng)求:篩選和查詢

GET 用來(lái)獲取資源。參數(shù)通常是可選的篩選條件,放在 URL 查詢參數(shù)里:

@GetMapping("/articles")
public List<Article> search(
        @RequestParam(required = false) String keyword,
        @RequestParam(defaultValue = "1") int page,
        @RequestParam(defaultValue = "20") int size) {
    return articleService.search(keyword, page, size);
}

如果要查某個(gè)具體資源,用路徑標(biāo)識(shí):

@GetMapping("/articles/{id}")
public Article getDetail(@PathVariable Long id) {
    return articleService.getById(id);
}

GET 請(qǐng)求沒(méi)有請(qǐng)求體,所以 @RequestBody 在 GET 中沒(méi)有意義。 雖然 HTTP 規(guī)范沒(méi)有明確禁止 GET 帶 Body,但大多數(shù) HTTP 客戶端和代理服務(wù)器會(huì)忽略 GET 的 Body,Spring 默認(rèn)也不支持。如果你發(fā)現(xiàn)自己想在 GET 里用 @RequestBody,大概率是接口設(shè)計(jì)有問(wèn)題,應(yīng)該改成 POST。

POST 請(qǐng)求:創(chuàng)建資源

POST 用來(lái)提交數(shù)據(jù)、創(chuàng)建資源。數(shù)據(jù)通常比較復(fù)雜,放在請(qǐng)求體里:

@PostMapping("/articles")
public Article create(@RequestBody @Valid ArticleCreateRequest request) {
    return articleService.create(request);
}

PUT 請(qǐng)求:更新資源

PUT 用來(lái)更新資源。被更新的資源用路徑標(biāo)識(shí),更新的內(nèi)容放請(qǐng)求體:

@PutMapping("/articles/{id}")
public Article update(
        @PathVariable Long id,
        @RequestBody ArticleUpdateRequest request) {
    return articleService.update(id, request);
}

這里 @PathVariable@RequestBody 同時(shí)出現(xiàn)——一個(gè)管"更新誰(shuí)",一個(gè)管"更新成什么",職責(zé)非常清晰。

DELETE 請(qǐng)求:刪除資源

DELETE 用來(lái)刪除資源,被刪除的對(duì)象用路徑標(biāo)識(shí):

@DeleteMapping("/articles/{id}")
public void delete(@PathVariable Long id) {
    articleService.delete(id);
}

把上面的規(guī)律總結(jié)成一張表:

HTTP 方法資源標(biāo)識(shí)請(qǐng)求數(shù)據(jù)典型注解組合
GET@PathVariable@RequestParam查詢列表 / 查看詳情
POST@RequestBody創(chuàng)建資源
PUT@PathVariable@RequestBody更新資源
DELETE@PathVariable刪除資源

使用時(shí)注意事項(xiàng)

@RequestBody 不能和 @RequestParam 混用在同一參數(shù)上

有些新手會(huì)寫出這種代碼:

// 錯(cuò)誤寫法
@PostMapping("/users")
public User create(@RequestBody @RequestParam UserDTO dto) {
    ...
}

這兩個(gè)注解的數(shù)據(jù)來(lái)源是矛盾的:@RequestBody 從請(qǐng)求體取,@RequestParam 從查詢參數(shù)取。一個(gè)參數(shù)不可能同時(shí)從兩個(gè)地方取值。Spring 會(huì)直接報(bào)錯(cuò)。

正確的做法是分清楚:哪些參數(shù)從查詢參數(shù)來(lái),哪些從請(qǐng)求體來(lái):

@PostMapping("/users")
public User create(
        @RequestParam(defaultValue = "false") Boolean notify,  // 查詢參數(shù)
        @RequestBody UserDTO dto) {                            // 請(qǐng)求體
    return userService.create(dto, notify);
}

@PathVariable 的變量名要和路徑占位符一致

// 如果占位符叫 {userId},參數(shù)名也得叫 userId
@GetMapping("/users/{userId}")
public User getUser(@PathVariable Long userId) { ... }

@RequestBody 的校驗(yàn)

@RequestBody 接收的對(duì)象通常需要校驗(yàn)。配合 @Valid 注解和 JSR-303 校驗(yàn)注解一起用:

public class UserCreateRequest {
    @NotBlank(message = "用戶名不能為空")
    private String name;

    @Email(message = "郵箱格式不正確")
    private String email;

    @Min(value = 0, message = "年齡不能為負(fù)數(shù)")
    private Integer age;
}

@PostMapping("/users")
public User create(@RequestBody @Valid UserCreateRequest request) {
    return userService.create(request);
}

不加 @Valid,校驗(yàn)注解不會(huì)生效,前端傳什么數(shù)據(jù)都能進(jìn)來(lái)。

接收數(shù)組或列表

@RequestBody 可以直接接收 JSON 數(shù)組:

@PostMapping("/users/batch")
public List<User> batchCreate(@RequestBody List<UserCreateRequest> requests) {
    return userService.batchCreate(requests);
}

前端傳一個(gè) JSON 數(shù)組就行:

[
    {"name": "張三", "email": "zhangsan@example.com"},
    {"name": "李四", "email": "lisi@example.com"}
]

小結(jié)

三種注解的本質(zhì)區(qū)別在于數(shù)據(jù)來(lái)源不同@RequestParam 從 URL 查詢參數(shù)取,@PathVariable 從 URL 路徑取,@RequestBody 從請(qǐng)求體取。不用死記語(yǔ)法,只需要跟著 HTTP 語(yǔ)義走:GET 查詢用 @RequestParam,資源標(biāo)識(shí)用 @PathVariable,復(fù)雜數(shù)據(jù)提交用 @RequestBody

以上就是SpringBoot中接口傳參的三大注解(RequestParam/RequestBody/PathVariable)全面解析的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot接口傳參注解的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • EVCache緩存在Spring Boot中的實(shí)戰(zhàn)示例

    EVCache緩存在Spring Boot中的實(shí)戰(zhàn)示例

    這篇文章主要介紹了EVCache緩存在Spring Boot中的實(shí)戰(zhàn)示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-12-12
  • springboot使用小工具之Lombok、devtools、Spring Initailizr詳解

    springboot使用小工具之Lombok、devtools、Spring Initailizr詳解

    這篇文章主要介紹了springboot使用小工具之Lombok、devtools、Spring Initailizr詳解,Lombok可以代替手寫get、set、構(gòu)造方法等,需要idea裝插件lombok,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • 基于SpringBoot打造一個(gè)通用CLI命令系統(tǒng)

    基于SpringBoot打造一個(gè)通用CLI命令系統(tǒng)

    在日常開(kāi)發(fā)中,某些情況下可能需要為服務(wù)提供一個(gè)命令行工具(CLI),方便運(yùn)維、調(diào)試或者遠(yuǎn)程調(diào)用業(yè)務(wù)接口,下面我們就來(lái)使用SpringBoot打造一個(gè)通用的CLI命令系統(tǒng)吧
    2025-12-12
  • jdbc中class.forname的作用

    jdbc中class.forname的作用

    這篇文章主要介紹了jdbc中class.forname的作用,使用示例說(shuō)明了他作用及使用方法,大家參考使用吧
    2014-01-01
  • 如何給Cacheable的key加上常量

    如何給Cacheable的key加上常量

    這篇文章主要介紹了如何給Cacheable的key加上常量的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 詳細(xì)分析Java 泛型的使用

    詳細(xì)分析Java 泛型的使用

    這篇文章主要介紹了Java 泛型的使用,文中講解非常詳細(xì),代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • java自定義線程模型處理方法分享

    java自定義線程模型處理方法分享

    本文給大家總結(jié)分享了下個(gè)人關(guān)于java處理自定義線程模型的一些經(jīng)驗(yàn)和處理方法,有需要的小伙伴可以參考下
    2016-08-08
  • Java項(xiàng)目中統(tǒng)計(jì)代碼耗時(shí)的工具類

    Java項(xiàng)目中統(tǒng)計(jì)代碼耗時(shí)的工具類

    相信大家在實(shí)際工具中,經(jīng)常需要做性能分析,做性能分析就少不了代碼執(zhí)行的耗時(shí)分析,本文將使用Java編寫一個(gè)項(xiàng)目統(tǒng)計(jì)代碼耗時(shí)的工具類,希望對(duì)大家有所幫助
    2025-08-08
  • Java中不常用但很好用的開(kāi)發(fā)小技巧分享

    Java中不常用但很好用的開(kāi)發(fā)小技巧分享

    其實(shí)干 Java 開(kāi)發(fā),必然離不開(kāi)一些計(jì)算,所以就會(huì)經(jīng)常用到 BigDecimal ,今天小編就來(lái)給大家分項(xiàng)一下那些不怎么常用,但是非常有用的方法,需要的可以參考一下
    2023-04-04
  • Java分治法與二分搜索算法實(shí)例分析

    Java分治法與二分搜索算法實(shí)例分析

    這篇文章主要介紹了Java分治法與二分搜索算法,簡(jiǎn)單講述了分治法與二分搜索算法的原理并結(jié)合java實(shí)例分析了二分搜索算法的實(shí)現(xiàn)與使用技巧,需要的朋友可以參考下
    2017-11-11

最新評(píng)論

吉安市| 柘荣县| 钟祥市| 延津县| 汝阳县| 乌鲁木齐县| 通海县| 永康市| 怀集县| 志丹县| 洪洞县| 长垣县| 金塔县| SHOW| 广饶县| 安顺市| 恭城| 和林格尔县| 彝良县| 洛浦县| 元谋县| 攀枝花市| 岱山县| 正蓝旗| 化隆| 高尔夫| 花垣县| 井冈山市| 苍南县| 秭归县| 茌平县| 呼伦贝尔市| 理塘县| 五河县| 北京市| 广德县| 桂阳县| 新巴尔虎左旗| 师宗县| 南昌市| 阿克苏市|