Spring MVC:@RequestParam 注解详解

Spring MVC @RequestParam 注解详解

适用范围:Spring MVC / Spring Boot Web(@RestController / @Controller

@RequestParam 用于把 HTTP 请求中的"请求参数(query string / 表单字段)"绑定到控制器方法的参数上

  • 常见参数来源:
    • URL 查询参数:/api/list?current=1&pageSize=10
    • 表单提交(application/x-www-form-urlencodedmultipart/form-data
    • multipart/form-data 中的普通字段与文件字段(文件字段通常用 MultipartFile 接收)

它解决的问题是:让你不用手动从 HttpServletRequest 里取参数,而是通过声明式方式直接拿到类型安全的 Java 参数。

演示(对比写法):

不使用 @RequestParam(手动取参):

java 复制代码
@PostMapping("/list")
public String list(HttpServletRequest request) {
    // URL: /list?current=1&pageSize=10
    String current = request.getParameter("current");
    String pageSize = request.getParameter("pageSize");
    return "current=" + current + ", pageSize=" + pageSize;
}

1. 基本用法

1.1 绑定同名参数

java 复制代码
@PostMapping("/list")
public BaseResponse<?> list(
        @RequestParam int current,
        @RequestParam int pageSize) {
    // ...
}

请求示例:

  • POST /admin/knowledge/list?current=1&pageSize=10
  • 或表单:current=1&pageSize=10

Spring 会将字符串参数自动转换为 int

1.2 指定参数名

java 复制代码
public String foo(@RequestParam("user_id") Long userId) {
    return "ok";
}

表示从请求参数 user_id 取值,绑定到 Java 参数 userId


2. 常用属性说明

@RequestParam 常见属性:

2.1 value / name

  • valuename 互为别名,都是请求参数名
java 复制代码
@RequestParam("name") String name
@RequestParam(name = "name") String name

2.2 required

  • 默认:true(必传)
  • 若请求中没有该参数:
    • required=true:抛异常(常见为 400 Bad Request)
    • required=false:参数为 null(或对基本类型需配合 defaultValue/改用包装类型)

示例:

java 复制代码
@RequestParam(value = "name", required = false) String name

2.3 defaultValue

  • 为参数提供默认值。
  • 一旦设置了 defaultValue,即使 required=true 也不会因为缺失而报错(会使用默认值)。

示例:

java 复制代码
@RequestParam(defaultValue = "1") int current,
@RequestParam(defaultValue = "10") int pageSize

3. 与 @RequestBody 的区别(非常重要)

  • @RequestParam:取 请求参数
    • query string:?a=1&b=2
    • 表单字段:a=1&b=2
    • multipart 表单字段
  • @RequestBody:取 请求体 body ,通常是 JSON
    • Content-Type: application/json
    • body:{"a":1,"b":2}

何时用哪个?

  • 传分页、过滤条件(简单字段)→ 常用 @RequestParam
  • 传复杂对象/列表 JSON → 常用 @RequestBody
  • 上传文件 → 常用 @RequestParam MultipartFile file

4. 实际例子解读

4.1 单文件上传 + 可选名称

java 复制代码
@PostMapping("/upload")
public BaseResponse<KnowledgeDocument> uploadDocument(
        @RequestParam("file") MultipartFile file,
        @RequestParam(value = "name", required = false) String name) {
    // ...
}

含义:

  • file:必传,来自 multipart 的文件字段名 file
  • name:可不传,来自 multipart 的普通字段 name

请求示例(multipart/form-data):

  • 表单字段:name=xxx
  • 文件字段:file=<选择文件>

4.2 分页与过滤条件

java 复制代码
@PostMapping("/list")
public BaseResponse<Page<KnowledgeDocument>> listDocuments(
        @RequestParam(defaultValue = "1") int current,
        @RequestParam(defaultValue = "10") int pageSize,
        @RequestParam(value = "name", required = false) String name,
        @RequestParam(value = "type", required = false) String type) {
    // ...
}

含义:

  • current:默认第 1 页
  • pageSize:默认每页 10 条
  • name/type:可选过滤条件,没传就是 null

4.3 多文件上传

java 复制代码
@PostMapping("/batch-upload")
public BaseResponse<BatchUploadResultVO> batchUploadDocuments(
        @RequestParam("files") MultipartFile[] files,
        @RequestParam(value = "names", required = false) List<String> names) {
    // ...
}

含义:

  • files:必传,multipart 中字段名 files,可上传多个文件(MultipartFile[]
  • names:可选,可传多个同名字段形成列表,例如:
    • names=文档1&names=文档2&names=文档3

5. 常见坑与建议

  1. 基本类型与 required=false

    • int current 无法为 null,如果你写 required=false 但不传,会报错。
    • 解决:
      • 用包装类型:Integer current
      • 或设置 defaultValue
  2. 参数名不一致导致绑定失败

    • 前端传的是 page_size,后端写的是 pageSize,会取不到。
    • 解决:显式指定:@RequestParam("page_size") int pageSize
  3. @RequestParam 不适用于 JSON body

    • 如果前端 Content-Type: application/json,参数在 body 里,必须用 @RequestBody(或对象接收)。
  4. 文件上传必须是 multipart

    • MultipartFile 只有在 multipart/form-data 下才会被正确解析。
相关推荐
行走的蜗牛8 小时前
【springai】 Model层设计与实现
java·ai编程
认真的薛薛8 小时前
Linux基础:GitOps发布流程
java·linux·运维
鱼鳞_8 小时前
苍穹外卖-Day05(Redis)
java·redis
用户398346161208 小时前
Go-Spring 实战第 10 课 —— 依赖注入的方式:字段注入和构造函数注入
spring·go
雨落在了我的手上8 小时前
初识java(九):类和对象(⼀)
java·开发语言
是码龙不是码农8 小时前
数据库主键选型:为什么别用自增 ID?
java·数据库
北风toto8 小时前
Jenkins新手入门安装插件全报错
java·运维·jenkins
罗超驿8 小时前
20.MySQL事务隔离级别示例详解(脏读、不可重复读、幻读)
java·数据库·mysql·面试
Dicky-_-zhang8 小时前
KubeEdge边缘部署实践
java·jvm