当前位置: 首页 > backend >正文

Spring MVC @RequestParam 注解怎么用?如何处理可选参数和默认值?

@RequestParam 注解的作用

@RequestParam 注解用于将 HTTP 请求中的请求参数(Query Parameters 或 Form Data)绑定到 Controller 方法的参数上。

  • Query Parameters: 出现在 URL 中 ? 之后的部分,格式为 key=value,多个参数用 & 分隔(例如:/search?query=spring&page=1)。
  • Form Data: 当浏览器提交 HTML 表单时,表单字段的值会作为请求参数发送。一般出现在 POST 请求中,Content-Typeapplication/x-www-form-urlencodedmultipart/form-data

基本用法

最简单的用法是,如果方法参数名与请求参数名相同,可以直接在方法参数前加上 @RequestParam 注解。Spring 会自动进行绑定和类型转换。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class SearchController {// 处理 /search?query=someValue@GetMapping("/search")@ResponseBodypublic String searchByQuery(@RequestParam String query) {// 此时 'query' 参数的值会被自动赋给方法参数 'query'return "Searching for: " + query;}// 处理 /data?id=123@GetMapping("/data")@ResponseBodypublic String getDataById(@RequestParam int id) {// Spring 会自动将请求参数 "123" (String) 转换为 int 类型return "Fetching data for ID: " + id;}
}

注意: 虽然在某些情况下,如果方法参数名和请求参数名完全一致,并且编译时保留了参数名信息(例如使用 Maven 或 Gradle 的特定配置),可以省略 @RequestParam 注解,但强烈建议始终显式使用 @RequestParam,以提高代码的可读性和明确性,并避免因编译配置变化导致的问题。

@RequestParam 的属性

@RequestParam 提供了一些属性来定制绑定行为:

  1. name (或 value):

    • 指定要绑定的请求参数的名称。当方法参数名与请求参数名不同时,必须使用此属性。
    • namevalue 是同义词。
    • 示例:@RequestParam(name = "user_id") Long userId 会将名为 user_id 的请求参数绑定到 userId 方法参数上。
  2. required:

    • 指定该参数是否必须存在于请求中。
    • 类型:boolean
    • 默认值:true。如果 required=true,但请求中没有该参数,Spring MVC 会抛出 MissingServletRequestParameterException 异常,导致 HTTP 400 (Bad Request) 响应。
    • 如果参数是可选的,需要设置为 required = false
  3. defaultValue:

    • 当请求中没有提供该参数,或者参数值为空字符串时,为其提供一个默认值。
    • 类型:String。Spring 会尝试将这个字符串默认值转换为方法参数的目标类型。
    • 注意: 使用 defaultValue 隐含了 required = false 的行为。即使你没有显式设置 required = false,只要提供了 defaultValue,该参数就不再是必需的。如果参数不存在,就会使用默认值,而不会抛出异常。
    • 如果参数存在但无法转换为目标类型(例如,请求 id=abc 但方法参数是 int),或者 defaultValue 无法转换为目标类型,会抛出类型转换异常。

处理可选参数和默认值

这是 @RequestParam 非常常见的用法:

场景 1:参数可选,如果不存在则为 null (对于对象类型) 或引发错误 (对于基本类型)

@GetMapping("/optional")
@ResponseBody
public String optionalParam(@RequestParam(name = "lang", required = false) String language, // 可选,不存在时 language 为 null@RequestParam(name = "count", required = false) Integer count) { // 可选,不存在时 count 为 nullString langMessage = (language != null) ? "Language: " + language : "Language not specified";String countMessage = (count != null) ? "Count: " + count : "Count not specified";return langMessage + ", " + countMessage;
}
// 请求 /optional -> "Language not specified, Count not specified"
// 请求 /optional?lang=en -> "Language: en, Count not specified"
// 请求 /optional?count=5 -> "Language not specified, Count: 5"
// 请求 /optional?lang=fr&count=10 -> "Language: fr, Count: 10"

注意: 如果可选参数是基本类型(如 int, boolean),并且你设置了 required=false 但没有 defaultValue,当请求中缺少该参数时,会尝试将 null 赋给基本类型,这将导致错误。因此,对于可选的基本类型参数,通常建议使用包装类型(Integer, Boolean)或提供 defaultValue

场景 2:参数可选,如果不存在则使用默认值

@GetMapping("/paged-search")
@ResponseBody
public String pagedSearch(@RequestParam(name = "q", required = false) String query, // 可选,默认为 null@RequestParam(name = "page", defaultValue = "1") int pageNumber, // 可选,默认为 1@RequestParam(name = "size", defaultValue = "10") int pageSize) { // 可选,默认为 10String queryInfo = (query != null) ? query : "all items";return String.format("Searching for '%s', Page: %d, Size: %d", queryInfo, pageNumber, pageSize);
}
// 请求 /paged-search -> "Searching for 'all items', Page: 1, Size: 10"
// 请求 /paged-search?q=spring -> "Searching for 'spring', Page: 1, Size: 10"
// 请求 /paged-search?page=3&size=20 -> "Searching for 'all items', Page: 3, Size: 20"
// 请求 /paged-search?q=java&page=2 -> "Searching for 'java', Page: 2, Size: 10"

最佳实践:
即使 defaultValue 隐含了 required=false,也建议同时显式设置 required=false,这样代码意图更清晰:
@RequestParam(name = "page", required = false, defaultValue = "1") int pageNumber

处理多值参数

如果一个请求参数可能出现多次(例如 /items?id=1&id=2&id=3),你可以将方法参数声明为 List 或数组类型。

@GetMapping("/items")
@ResponseBody
public String getItemsByIds(@RequestParam(name = "id") List<Long> ids) {// ids 会包含 [1, 2, 3]return "Fetching items with IDs: " + ids;
}@GetMapping("/tags")
@ResponseBody
public String getItemsByTags(@RequestParam(name = "tag", required = false) String[] tags) {if (tags == null || tags.length == 0) {return "No tags specified.";}// tags 会包含 ["java", "spring"] 如果请求是 /tags?tag=java&tag=springreturn "Fetching items with tags: " + Arrays.toString(tags);
}

绑定所有请求参数到 Map

如果你想获取所有请求参数,可以将 @RequestParam 应用于 Map<String, String>MultiValueMap<String, String>

import org.springframework.util.MultiValueMap;
import java.util.Map;// ...@GetMapping("/allParams")
@ResponseBody
public String getAllParams(@RequestParam Map<String, String> allParams) {// allParams 包含所有请求参数的 key-value 对// 如果一个 key 有多个值,Map 只会保留其中一个(行为可能依赖具体实现)return "Received params: " + allParams.toString();
}@GetMapping("/multiParams")
@ResponseBody
public String getAllMultiParams(@RequestParam MultiValueMap<String, String> allParams) {// MultiValueMap 可以处理一个 key 对应多个值的情况// 例如 /multiParams?name=a&name=b&type=x -> allParams 包含 {"name": ["a", "b"], "type": ["x"]}return "Received multi-value params: " + allParams.toString();
}

总结

  • @RequestParam 用于将请求参数(Query Params, Form Data)绑定到方法参数。
  • 使用 namevalue 属性指定请求参数名(如果与方法参数名不同)。
  • 使用 required = false 使参数变为可选(不存在时,对象类型为 null,基本类型需小心或用包装类/defaultValue)。
  • 使用 defaultValue = "value" 为可选参数提供默认值(参数不存在或为空时生效,隐含 required=false)。
  • 可以将多值参数绑定到 List 或数组。
  • 可以将所有参数绑定到 MapMultiValueMap
  • Spring 自动进行类型转换,如果转换失败会报错。
http://www.xdnf.cn/news/3296.html

相关文章:

  • 温补晶振(TCXO)稳定性优化:从实验室到量产的关键技术
  • 【爬虫】deepseek谈爬虫工具
  • Java 多线程进阶:什么是线程安全?
  • 如何在 Linux 环境下使用 Certbot 自动生成 SSL 证书并部署到 Nginx 服务中
  • 【论文阅读】APMSA: Adversarial Perturbation Against Model Stealing Attacks
  • 7.软考高项(信息系统项目管理师)-资源管理
  • C++初阶-string类2
  • [PRO_A7] SZ501 FPGA开发板简介
  • Roboflow标注数据集
  • crashpad 编译
  • 时态--00--总述
  • 1254. 【动态规划】单词的划分
  • KUKA机器人不同的用户权限详细介绍
  • vue+django农产品价格预测和推荐可视化系统[带知识图谱]
  • 0901context_useReducer_状态管理-react-仿低代码平台项目
  • 如何写好Verilog状态机
  • 【Bootstrap V4系列】学习入门教程之 布局
  • w~大模型~合集14
  • 用电数据 一网打尽“多回路计量电表”让能耗管理更简单
  • 【文献分享】Modelling the species-area提供数据和代码
  • 技术研究 | 推荐系统训练后多分类属性遗忘:双组分损失优化与效用空间正则设计
  • GitHub修炼法则:第一次提交代码教学(Liunx系统)
  • Redis Info 性能指标描述
  • AIGC 大模型微调实战:中小企业如何用自有数据训练专属 AI 模型?
  • TCP三次握手、四次挥手+多线程并发处理
  • 昆仑万维:AI短剧出海布局,中型公司如何突破AI商业化?
  • 可视化图解算法:判断是否完全二叉树
  • PH热榜 | 2025-04-30
  • 如何使用C语言手搓斐波那契数列?
  • 如何设计一个100w QPS高并发抢券系统