SpringMvc,全面讲解@RequestParam注解的用法和原理

2023-11-14

本文要讲的@RequestParam注解大家在开发中应该会经常的用到,但是它的某些用法我感觉你不一定都知道,所以这篇文章就讲解一下带大家拨开云雾全面了解这个注解,使大家在开发中使用到这个注解的时候不再一知半解。

先看一下@RequestParam这个注解的源码:


@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
 /**
  * 对应request中参数名称
  */
  @AliasFor("name")
  String value() default "";
  /**
  * 同value
  */
  @AliasFor("value")
  String name() default "";
 /**
  * 请求中是否必须有这个参数,默认为true,
  * 如果使用默认的true,前台没有传递这个参数会报错。
  */
  boolean required() default true;

}

好了下面举几个例子带大家去全面了解这个注解的用法。

1:@RequestParam 指定 name,获取对应参数的值。第一个例子应该就有你不知道的用法,仔细看。

/**
     * 中指定name,用来取name的值对应的请求参数中的值
     * @param name:可以不传递name参数,不传递的时候默认值为ready
     * @param age
     * @param pets
     * @return
     */
    @RequestMapping("/requestparam/test1")
    public Map<String, Object> test1(
            @RequestParam(value = "name", required = false, defaultValue = "ready") String name,
            //相当于request.getParameter("name")
            @RequestParam("age") int age,
            //Integer.parseInt(request.getParameter("age"))
            @RequestParam("interests") String[] interests,
            //request.getParameterValues("pets")
            // 这个解释以下,如果你传递多个pets,会自动给你分装成一个list,这个用法还是挺牛的。
            @RequestParam("pets") List<String> pets 
            //Arrays.asList(request.getParameterValues("pets"))
    ) {
        Map<String, Object> result = new LinkedHashMap<>();
        result.put("name", name);
        result.put("age", age);
        result.put("interests", interests);
        result.put("pets", pets);
        return result;
    }

我们使用postman测试一下:

上面传递的参数interests,pets传递多个值,参数使用集合或者数组接收@RequestParam会为你自动转换成数组或者集合。

2:required 属性为 true,不传,则报错如下age不传值就报错了,但是当你把require设置为false的时候就访问正常了:

3:@RequestParam 不指定 name,获取所有参数值,这个开发中不建议大家这样使用,因为你不知道有几个具体参数值,但是某些功能的开发会使用到,要了解一下。

当我们想用一个 Map 来接收所有参数的之后,代码如下,@RequestParam 不用指定 name 的值,参数类型为 Map<String,String>,所有请求参数会以参数名称:值的方式丢在 Map 中。代码如下:


/**
     * 不指定name,用于接收所有参数的值,
     * 参数类型为Map<String,String>,key为请求中的参数名称,
     * value为值
     * @param paramMap
     * @return
     */
    @RequestMapping("/requestparam/test2")
    public Map<String, String> test2(@RequestParam Map<String, String> paramMap) {
        return paramMap;
    }

 我们使用postman调用一下如下图:

当你直接使用map接收的时候,Interests或者pets只会取我们传递的第一个值,这样在开发中就有问题了,我们明明要给后台传输多个值,但是没收到。这个时候你就想了这是严重的bug啊,开发中万一我们一定要使用map接收呢?别慌还有下面使用方法的。

3.2:@RequestParam 不指定 name,获取所有参数值。这个接口的参数是MultiValueMap类型。代码如下:

/**
     * 不指定name,用于接收所有参数的值,
     * 参数类型为MultiValueMap<String, String>:
     * key为请求中的参数名称,value为值的集合List<String>
     * @param paramMap
     * @return
     */
    @RequestMapping(value = "/requestparam/test3", produces = MediaType.APPLICATION_JSON_VALUE)
    public MultiValueMap<String, String> test3(@RequestParam MultiValueMap<String, String> paramMap) {
        return paramMap;
    }

 使用postman调用一下如下图:

 参数是MultiValueMap类型,这玩意是干啥的?好像很陌生啊,哈哈再陌生的东西,把其源码放出来,瞬间明了了,如下代码,可以看出来MultiValueMap相当于Map<String,List<String>>。大家可以记住这种数据结构,开发中遇到这种数据结构的功能,直接使用MultiValueMap十分的好用。

public interface MultiValueMap<K, V> extends Map<K, List<V>> {
  /**
   * Return the first value for the given key.
   * @param key the key
   * @return the first value for the specified key, or {@code null} if none
   */
  @Nullable
  V getFirst(K key)

好了总结一下@RequestParam这个注解的用法:

1:@RequestParam 注解用来标注在控制器方法的参数上,springmvc 从 request 中获取请求的值赋值给方法的参数。

2:@RequestParam 指定 name 时,可以获取 request 中指定参数的值,相当于 request.getParameter(name)或 request.getParameters(name)。

3:@RequestParam 未指定 name,参数类型为:Map<String,String>时,用来接收 request 中所有参数的值,Map 中 key 为参数名称,value 为参数的值。

4:@RequestParam 未指定 name,参数类型为 MultiValueMap<String, String>时,用来接收 request 中所有参数的值,key 为请求中的参数名称,value 为值的集合 List<String>。

看过上面几个例子你应该完全了解了@RequestParam的用法了吧。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringMvc,全面讲解@RequestParam注解的用法和原理 的相关文章

  • 将 Spring Data 随机(嵌入式)Mongo 端口与 NoSQL JUnit @Rule 结合使用

    我目前正在尝试编写一个使用 Spring Data Mongo 存储库的集成测试类 我使用由提供的嵌入式 Mongo 实例de flapdoodle embed mongo依赖性 Spring Data 文档指定我们只需要将这个依赖项放入项
  • JavaFx ComboBox 绑定混乱

    我有一个 I18N 实现 它通过属性绑定 JavaFX UI 元素 例如 def translateLabel l Label key String args Any Unit l textProperty bind createStrin
  • 由于保存之前/之后的 CSV 差异而导致错误解析(Java w/ Apache Commons CSV)

    我有一个 37 列的 CSV 文件 我正在使用 Apache Commons CSV 1 2 在 Java 中解析该文件 我的设置代码如下 initialize FileReader object FileReader fileReader
  • 构建 jar 后无法运行 exe

    我制作了一个简单的实用应用程序 其中我有一个要运行的exe文件 我通过使用它来运行 Runtime getRuntime exec this getClass getResource filename exe getPath 当我从 ide
  • 在 Java 构建过程中更改常量的最佳方法

    我继承了一个在 Tomcat 下运行的 Java 应用程序 servlet 由于历史原因 根据应用程序的部署位置 本质上是品牌问题 代码具有不同的 外观和感觉 选项 有几个常量控制这个品牌过程 它们具有不同的功能 不应压缩为单个常量 即 B
  • Spring Boot“没有可用消息”错误(状态 = 404),

    我正在使用带有嵌入式 Tomcat 的 Spring Boot 当它启动时 它会登录到控制台 s w s m m a RequestMappingHandlerMapping 将 home 映射到公共 java lang String co
  • 无法解析导航抽屉中片段中的 getSystemService

    我正在尝试实现一个导航抽屉 其中有一个片段中的地图 这是我的代码 这里是fragment map xml
  • Android 在 ROOM 数据库中插入大量数据

    我有大约 10 个模型 每个模型都有超过 120K 行和 90 列的记录 其中包含双数组值 在 Room 中插入任何模型都需要超过 125 130 秒 任何人都可以建议我需要做什么才能使用一些批量插入技术来保存所有这些 120K 该技术大约
  • Android - Firebase - 保存新数据而不覆盖旧数据

    创建此问题是因为我之前的问题包含 2 个问题 而不是将其缩小到 1 Aim 用户将能够存储新数据而不会覆盖之前提交的数据 描述 目前 当用户输入新报告时 事件报告节点中的用户事件报告数据将被覆盖 用户发送的旧事件报告中的数据应与新数据一起保
  • 使用 python 中的 java 库

    我有一个 python 应用程序和 java 应用程序 python 应用程序为 java 应用程序生成输入并在命令行上调用它 我确信一定有一个更优雅的解决方案 就像使用 JNI 从 Java 调用 C 代码一样 有什么指点吗 仅供参考 我
  • 适当支持不区分大小写的映射

    我想实现一个不区分大小写的哈希映射 这个问题本身并不新鲜 但我想添加额外的功能 但不知道要采取什么总体方向 我希望客户能够做这样的事情 boolean preserve case true Map
  • 运行Java程序时出错

    我正在尝试使用 netbeans 运行我的 java 程序 但收到此错误 有什么建议吗 Exception in thread AWT EventQueue 0 java lang NullPointerException at javax
  • 非法监控状态异常

    如何将轮询线程传递给另一个线程进行处理 程序执行在控制器类中 该类具有 main 方法和线程池 主类控制器 public static void main String args throws InterruptedException Ru
  • Java 中的逻辑回归

    我们需要用 Java 进行逻辑回归 我们在 Python 中使用了这段代码http blog smellthedata com 2009 06 python logistic regression with l2 html http blo
  • 使用 Hibernate 作为 ORM 机制的 Web 应用程序中的 L1 和 L2 缓存有什么区别?

    我只想要一些有关使用 L1 缓存和 L2 缓存的标准用途的一般信息 我很好奇 因为我正在研究使用赤土陶器作为二级缓存的系统 并且我发现它也有一级缓存 L1 缓存是每个 Hibernate 会话都存在的缓存 并且该缓存不在线程之间共享 该缓存
  • 带有 CONTAINS 查询的PreparedStatement

    我有一个查询需要连续运行 28000 次 所以我认为使用准备好的语句可能是一个聪明的主意 这是我的查询 String requestWithFirstName SELECT SE ELEMENT ID SE LASTNAME SE FIRS
  • 如何告诉杰克逊在反序列化期间忽略空对象?

    在反序列化过程中 据我理解是将JSON数据转换为Java对象的过程 我如何告诉Jackson 当它读取不包含数据的对象时 应该忽略它 我正在使用 Jackson 2 6 6 和 Spring 4 2 6 我的控制器收到的JSON数据如下 i
  • 如何获取嵌套类型内部结构的所有类型?

    我有一个函数如下 public void park List
  • OkHttp javax.net.ssl.SSLPeerUnverifiedException:主机名domain.com未验证

    我几天来一直在努力让它发挥作用 我正在尝试通过以下方式连接到我的服务器https带有自签名证书 我认为现在没有任何页面或示例是我未读过的 我做了什么 按照本教程创建了 bks 密钥库 http blog crazybob org 2010
  • 我可以在方法体内使用注释吗?

    允许 Java 注释的语义将它们放置在某处在函数体内 例如注释特定的函数调用 语句或表达式 例如 class MyClass void theFunc Thing thing String s null Catching NullPoint

随机推荐

  • 零基础小白入门Python,值得看的几本书籍

    Python目前是全球4大流行编程语言之一 根据今年TIOBE最新排名 Python已超越C 与Java C C 一起成为全球前4大最流行语言 指数变化一直呈现出上升的趋势 TIOBE最新排名 众所周知 Python应用广泛 涵盖后端开发
  • 创业因何维艰,细数可能会死的几个关键节点

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 云视链等几个创业团队被扒皮之后 创业者的品行问题开始被摆到了桌面上来讨论 整个社会开始了一场 创业者 的反思潮 而 霸道总裁 余佳文不合适宜的言论再一次将这股浪潮推向了巅峰
  • 获取磁盘信息函数statvfs()

    对应的头文件 include
  • 【ES】Elasticsearch 简介

    大数据开发经常用到 Elasticesearch 今天做一下介绍 1 Elasticsearch 简介 Elaticsearch 简称为 ES 是一个开源的高扩展的分布式全文检索引擎 特点 近乎实时的存储 检索数据 扩展性好 可以扩展到上百
  • 元组的详细操作

    一 创建元组 name chinese gansu beijing 创建空元组 name 元组中只包含一个元素时 需要在元素后面添加逗号消除歧义 name chinese 二 访问元组 元组可以使用下标索引来访问元组中的值 name chi
  • RK356x Android11更换默认的Launcher

    1 开发环境 ubuntu版本 18 04 开发平台 RK356x Android版本 android11 2 目的 android11 系统自带了一个启动器Launcher3 在android源码路径下的packages apps Lau
  • 机器学习之深度神经网络

    目录 卷积神经网络与全连接神经网络 前向后向传播推导 通用手写体识别模型 人脸识别模型 电影评论情感分析模型 卷积神经网络与全连接神经网络 卷积神经网络 Convolutional Neural Network CNN 和全连接神经网络 F
  • 数据结构——普里姆(Prim)算法

    普里姆算法 Prim算法 图论中的一种算法 可在加权连通图里搜索最小生成树 意即由此算法搜索到的边子集所构成的树中 不但包括了连通图里的所有顶点 且其所有边的权值之和亦为最小 以下是数据结构中关于普里姆算法的操作 编程风格参考严蔚敏版数据结
  • 实施运维企业面试题-5

    NETWORK 1 请描述 TCP IP 协议中主机与主机之间通信的三要素 参考答案 IP 地址 IP address 子网掩码 subnet mask IP 路由 IP router 2 请描述 IP 地址的分类及每一类的范围 参考答案
  • Graphormer复现碎碎念

    一 简介 Graphormer https github com microsoft Graphormerhttps github com microsoft Graphormer 二 安装 使用 install sh安装 前面是pip直接
  • localStorage的过期时间设置的方法?——和派孔明

    我们都知道localStorage不主动删除 永远不会销毁 那么如何设置localStorage的过期时间呢 今天我们来一起尝试一下
  • C++与STL基础二:栈stack与前中后缀表达式的应用

    C 与STL基础二 栈stack与前中后缀表达式的应用 栈 stack 是一种具有特定操作规则的数据结构 它遵循后进先出 LIFO 的原则 在C 中 我们可以使用STL 标准模板库 中的stack类来实现栈的功能 本文将介绍栈及其常见应用之
  • Python之numpy教程(二):运算、索引、切片

    1 numpy数组的特点在于 大小相等的数组之间 任何算数运算都会将运算应用到元素级 请看下面的例子 arr np array 1 2 3 4 5 6 arr输出 array 1 2 3 4 5 6 arr arr输出 array 1 4
  • opencv实现阈值分割

    文章目录 基础函数 直方图阈值 实现 threshold 函数使用 三角法阈值 实现 迭代法阈值 算法步骤 Python语法补充 实现 大津法 理论 cv实现 底层复现 自适应阈值 理论 具体操作步骤 优化 CV实现 底层复现 基础函数 在
  • 基于SSM+Vue的汽车售票网站的设计与实现

    末尾获取源码 开发语言 Java Java开发工具 JDK1 8 后端框架 SSM 前端 采用Vue技术开发 数据库 MySQL5 7和Navicat管理工具结合 服务器 Tomcat8 5 开发软件 IDEA Eclipse 是否Mave
  • [前端系列第6弹]Ajax简明教程:轻松实现Web页面的异步交互

    在这篇文章中 我将介绍Ajax的基本概念 原理 优缺点 实现方法和应用场景 以及如何使用它来实现Web页面的异步交互 还将给一些简单而实用的例子 让你可以跟着我一步一步地编写自己的Ajax代码 目录 一 什么是Ajax 二 如何使用Ajax
  • gdb调试多进程程序和多线程程序

    gdb调试多进程程序和多线程程序 平时一般用gdb直接调试短小的程序 好像我还没调试过多进程和多线程程序呢 1 gdb调试多进程程序 如果一个进程通过fork系统调用创建了子进程 gdb会继续调试原来的进程 子进程则正常运行 常用的有两种方
  • win10设置任务栏双屏不同位置(方向)

    在所有显示器上显示任务栏开 任务栏在屏幕的位置 底部 在所有显示器上显示任务栏 任务栏在屏幕的位置靠右 在所有显示开 win10双屏设置任务栏位置方向 哔哩哔哩 bilibili
  • 重定义;多次初始化(C++报错)

    C 中报错 b 重定义 多次初始化 如图 将a b c前面的int数据类型去掉即可
  • SpringMvc,全面讲解@RequestParam注解的用法和原理

    本文要讲的 RequestParam注解大家在开发中应该会经常的用到 但是它的某些用法我感觉你不一定都知道 所以这篇文章就讲解一下带大家拨开云雾全面了解这个注解 使大家在开发中使用到这个注解的时候不再一知半解 先看一下 RequestPar