HandlerMethodArgumentResolver :深入spring mvc参数解析机制

❃博主首页 : <码到三十五>
☠博主专栏 : <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关>
♝博主的话 : 搬的每块砖,皆为峰峦之基;公众号搜索(码到三十五)关注这个爱发技术干货的coder,一起筑基 !

HandlerMethodArgumentResolver 是 Spring MVC 框架中的一个关键组件,用于解析控制器(Controller)方法的参数。在 Spring MVC 中,当一个请求到达时,DispatcherServlet 会负责找到对应的处理器(即控制器中的方法)来处理这个请求。在处理之前,需要解析方法的参数,这就是 HandlerMethodArgumentResolver 的作用

导读

      • 一、HandlerMethodArgumentResolver简介
      • 二、工作原理和流程
        • 1. 接口定义与功能
        • 2. 工作流程
          • 2.1 确定解析器
          • 2.2 解析参数
          • 2.3 异常处理
      • 三、内置解析器
      • 四、自定义解析器
        • 实现步骤
        • 常用场景
        • 用法方法
      • 五、结语

一、HandlerMethodArgumentResolver简介

HandlerMethodArgumentResolver 是 Spring MVC 提供的一个接口,用于将 HTTP 请求中的数据解析并绑定到控制器方法的参数上。它定义了两个主要的方法:supportsParameterresolveArgumentsupportsParameter 方法用于判断当前解析器是否支持给定的方法参数,而 resolveArgument 方法则用于实际解析请求中的数据,并将其作为参数值返回。

下图是mvc处理流程:
在这里插入图片描述

HandlerMethodArgumentResolver 的主要职责是解析控制器方法的参数。这意味着当 Spring MVC 调用一个控制器方法时(上图第6步),它使用这个解析器来将请求中的数据(如请求参数、路径变量、请求体等)转换为方法参数的具体值

HandlerMethodArgumentResolver 是 Spring MVC 框架中的一个核心接口,其工作原理主要围绕如何将 HTTP 请求中的数据解析并绑定到控制器(Controller)方法的参数上。以下是该接口工作原理的详细介绍:

二、工作原理和流程

1. 接口定义与功能

HandlerMethodArgumentResolver 接口定义了两个主要方法:

  • boolean supportsParameter(MethodParameter parameter): 用于判断当前解析器是否支持给定的方法参数。这通常基于参数的注解或类型来决定。
  • Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception: 用于实际解析请求中的数据,并将其作为参数值返回。如果在解析过程中遇到错误,该方法可能会抛出异常。

在这里插入图片描述

2. 工作流程

当 Spring MVC 接收到一个 HTTP 请求并确定要调用的控制器方法后,它会按照以下步骤使用 HandlerMethodArgumentResolver 来解析方法的参数:

2.1 确定解析器

Spring MVC 会遍历所有已注册的 HandlerMethodArgumentResolver 实现,并调用每个解析器的 supportsParameter 方法来检查是否有解析器支持当前方法的参数。一旦找到支持的解析器,就会使用该解析器来解析参数。

2.2 解析参数

一旦确定了合适的解析器,Spring MVC 就会调用该解析器的 resolveArgument 方法来实际解析请求中的数据。这个过程可能涉及从请求头、请求体、路径变量、查询参数等不同来源提取数据,并将其转换为方法参数所需的类型。

2.3 异常处理

如果在解析过程中发生异常,解析器通常会抛出一个异常,该异常随后会被 Spring MVC 的异常处理机制捕获并处理。这允许开发者为不同的异常类型提供自定义的错误响应。

三、内置解析器

Spring MVC 提供了多种内置的 HandlerMethodArgumentResolver 实现,用于处理不同类型的请求参数,如:

  • ServletRequestParamMethodArgumentResolver:解析请求参数中的查询参数。
    在这里插入图片描述

  • PathVariableMethodArgumentResolver:解析请求参数中的路径变量。

  • RequestHeaderMethodArgumentResolver:解析请求头中的参数。

  • RequestBodyMethodArgumentResolver:解析请求体中的参数,通常用于处理 JSON 或 XML 数据。

  • ServletModelAttributeMethodProcessor:处理带有 @ModelAttribute 注解的参数,用于将请求参数绑定到模型对象上。

四、自定义解析器

除了内置解析器外,Spring MVC 还允许开发者自定义 HandlerMethodArgumentResolver 实现类,以处理特殊的参数类型或实现自定义的解析逻辑。自定义解析器需要实现 HandlerMethodArgumentResolver 接口,并覆盖 supportsParameterresolveArgument 方法。然后,通过注册自定义解析器到 Spring MVC 的配置中,使其能够参与到参数解析的过程中。

实现步骤

自定义HandlerMethodArgumentResolver一般包含以下步骤:

  1. 创建自定义解析器类,实现 HandlerMethodArgumentResolver 接口。
  2. 覆盖 supportsParameter 方法,定义该解析器支持的参数类型或注解。
  3. 覆盖 resolveArgument 方法,实现自定义的参数解析逻辑。
  4. 在 Spring MVC 配置中注册自定义解析器。
常用场景

自定义HandlerMethodArgumentResolver通常在以下情况下使用:

  • 当需要解析的请求参数类型不是 Spring MVC 默认支持的。
  • 当需要在参数解析过程中添加特定的逻辑,如权限检查、数据验证等
用法方法

下面代码中,创建一个自定义解析器来解析一个自定义的注解 @CurrentUser,该注解用于将当前用户的信息注入到控制器方法的参数中。

首先,定义 @CurrentUser 注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}

然后,创建自定义的 HandlerMethodArgumentResolver

import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.stereotype.Component;@Component
public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {@Overridepublic boolean supportsParameter(MethodParameter parameter) {return parameter.hasParameterAnnotation(CurrentUser.class) && parameter.getParameterType().equals(User.class);}@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {// 假设已经有获取当前用户的方法User currentUser = getCurrentUser(webRequest);return currentUser;}private User getCurrentUser(NativeWebRequest webRequest) {// 这里是你的逻辑来获取当前用户,例如从Session或Security Context中// 返回一个新的User实例return new User(); }
}

最后,在控制器中使用这个注解:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@GetMapping("/user/info")public String getUserInfo(@CurrentUser User currentUser) {// 这里可以使用currentUser对象,它已经被解析器填充了return "User info for: " + currentUser.getName(); }
}

别忘了在Spring配置中注册这个解析器,如果使用的是Java配置,可以在配置类中添加:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.List;@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate CurrentUserArgumentResolver currentUserArgumentResolver;@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {resolvers.add(currentUserArgumentResolver);}
}

这样,当访问 /user/info 端点时,CurrentUserArgumentResolver 将会被调用,并将当前用户的信息注入到 getUserInfo 方法的 currentUser 参数中。

五、结语

HandlerMethodArgumentResolver 是 Spring MVC 框架中用于解析请求参数的关键接口。通过内置解析器和自定义解析器,Spring MVC 提供了灵活而强大的参数解析能力,使得开发者可以轻松处理各种复杂的请求参数场景。深入理解 HandlerMethodArgumentResolver 的工作原理对于掌握 Spring MVC 框架的请求处理流程和提高开发效率具有重要意义。


关注公众号获取更多技术干货 !

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/40973.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编程新纪元:AI辅助工具豆包Marscode体验

自从ChatGPT带动全球AI热潮&#xff0c;AI席卷着各行各业。编程界也不例外&#xff0c;早期做过了Github Copilot、阿里的通义灵码等AI编程插件的体验 p.s.以上的下载量与评分均只是plugins.jetbrains的marketplace数据&#xff0c;仅供参考 基本AI编程工具的功能都差不多&…

自然语言处理学习(3)RNN 模型学习---NLP领域的第一个模型

一 基本定义 视频链接 1.小案例理解–语义理解 目的&#xff1a;输入一句话&#xff0c;机器需要理解这句话的语义 二. RNN模型分类 1. 按照输入输出分类 (1) N Vs N (2) N Vs 1 (3) 1 VsN (4) seq2seq 三 传统RNN模型 1. 内部结构分析 &#xff08;a) 总体外…

基于单片机的多功能电子时钟的设计

摘要&#xff1a;提出了一种基于单片机的多功能电子时钟的设计方法&#xff0c;以 AT89C52单片机作为系统的主控芯片&#xff0c;采用DS1302作为时钟控制芯片&#xff0c;实现日期时钟显示并且提供精准定时的功能。此外&#xff0c;还可经由DHT22所构成的温湿度传感电路&#x…

Kafka集群部署(手把手部署图文详细版)

1.1.1 部署zookpeer 在node02下载并解压zookeeper软件包 cd /usr/local wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz 或者&#xff1a;scp cat192.168.28.100:/home/cat/zookeeper-3.4.6.tar.gz /tmp&#xff08;注意目录&#xf…

vue属性绑定v-bind

属性绑定v-bind 双大括号不能在HTML attributes 中使用。想要响应式地绑定一个attribute&#xff0c;应该使用v-bind指令。 v-bind 指令指示Vue将元素id attribute 与组件的dyid属性保持一致。如果绑定值是null或者undefined&#xff0c;那么该attribute将会从渲染的元素上移…

昇思第9天

LSTMCRF序列标注 序列标注&#xff1a;对序列进行标注&#xff0c;实际上是对序列中每个Token进行标签预测&#xff0c;可以直接视作简单的多分类问题。但是序列标注不仅仅需要对单个Token进行分类预测&#xff0c;同时相邻Token直接有关联关系&#xff0c;需要引入一种能够学…

docker介绍与详细安装

1 docker 介绍 1.1 虚拟化 在计算机中&#xff0c;虚拟化&#xff08;英语&#xff1a;Virtualization&#xff09;是一种资源管理技术&#xff0c;是将计算机的各种实体资源&#xff0c;如服务器、网络、内存及存储等&#xff0c;予以抽象、转换后呈现出来&#xff0c;打破实…

【BUUCTF-PWN】12-get_started_3dsctf_2016

32位&#xff0c;开启了NX保护 执行效果&#xff1a; main函数&#xff1a; 其中gets()函数存在栈溢出&#xff0c;溢出距离为0x38&#xff0c;这里是使用的esp寻址&#xff0c;属于外平栈&#xff0c;不需要覆盖ebp的四个字节。而之前做的题一般都是ebp寻址&#xff0c;…

开发国际短剧系统的策略解析

一、明确项目目标和需求 1、功能需求&#xff1a;确定系统应具备的基本功能&#xff0c;如用户注册、登录、浏览短剧、评论、分享、个性化推荐等。 2、性能需求&#xff1a;确保系统能够承受高并发访问&#xff0c;保证视频流畅播放&#xff0c;减少卡顿和延迟。 3、跨文化传播…

MCU中如何利用串口通信,增加AT指令框架

第一步&#xff0c;通过串口与PC端建立通信第二步&#xff0c;根据PC端发来的AT指令&#xff0c;MCU执行相应代码 主要是解析PC端发来的字符串&#xff0c;也就是获取字符串、处理字符串、以及分析字符串。 1. 串口通信 用到的是DMA串口通信&#xff0c;收发字符串数据时&…

如何使用 3D 建模库在 C# 中将 3DS 转换为 USDZ?

USDZ/USD是一种 3D 文件格式&#xff0c;被广泛用于跨平台共享 3D 资产。另一方面&#xff0c;3DS是另一种以块形式存储数据的 3D 文件格式。在某些情况下&#xff0c;您需要将3DS 文件转换为 USDZ/USD文件格式。因此&#xff0c;本篇博文介绍了一个功能丰富的3D 建模库&#x…

【基于R语言群体遗传学】-6-表型计算等位基因频率、最大似然估计方法

到目前为止&#xff0c;我们主要讨论了等位基因和基因型频率&#xff0c;以及我们如何可以从一个推断出另一个。但是&#xff0c;如果我们不知道等位基因频率&#xff0c;只知道种群中存在哪些表型呢&#xff1f;如果我们足够幸运&#xff0c;知道哪些表型对应哪些基因型&#…

一键安装部署,在 Ubuntu 服务器上快速搭建基于 Ghost CMS的网站

我们在上一篇内容中讲过&#xff0c;如何使用 Helm 在 Kubernetes 集群上安装 WordPress&#xff0c;创建高可用性网站。而这次我们将基于另一个流行的内容管理系统 Ghost CMS 在 DigitalOcean 云主机进行建站。 Ghost 也是开源的内容管理系统&#xff08;CMS&#xff09;&…

C#知识|项目的实施过程及通用三级架构的搭建笔记

哈喽,你好啊,我是雷工! 01 项目需求分析 根据与需求方沟通,分析需求,一般都有需求分析师来进行项目需求收集与分析。 根据需求文档进行项目功能设计。 02 框架的选择 ①小项目可以根据需求选择两层或三层结构。 ②中型大型项目,至少需要三层架构和其他架构的组合。 03 框…

Spring学习03-[Spring容器核心技术IOC学习进阶]

IOC学习进阶 Order使用Order改变注入顺序实现Ordered接口&#xff0c;重写getOrder方法来改变自动注入顺序 DependsOn使用 Lazy全局设置-设置所有bean启动时候懒加载 Scopebean是单例的&#xff0c;会不会有线程安全问题 Order 可以改变自动注入的顺序 比如有个animal的接口&a…

NEMU模拟器的gdb调试和指令调试

NEMU模拟器的gdb调试和指令调试 1 通过gdb调试NEMU1.1 编译NEMU1.2 gdb调试 2 通过NEMU调试指令 关于如何编译NEMU&#xff0c;以及编译MySBIBenOS固件&#xff0c;运行等前置知识&#xff0c;可参考 《NEMU模拟器源码编译与使用》。 1 通过gdb调试NEMU 1.1 编译NEMU 当我使…

E2.【C语言】练习:static部分

#include <stdio.h> int sum(int a) {int c 0;static int b 3;c 1;b 2;return (a b c); } int main() {int i;int a 2;for (i 0; i < 5;i){printf("%d ", sum(a));} } 求执行结果 c是auto类变量(普通的局部变量)&#xff0c;自动产生&#xff0c…

Windows 11 操作无法完成(错误 0x00000709)。

这里写自定义目录标题 环境错误一错误二错误三重点 环境 共享端&#xff1a;Win11 专业版 23H2 本地端&#xff1a;Win11 专业版 23H2 错误一 操作无法完成(错误 0x00000709)。 再次检查打印机名称&#xff0c;并确保打印机已连接到网络。 解决&#xff1a; 组策略设置 打开…

sql查询 只取某字段重复数据中的一条

一. 前提条件 某表的主键由两个字段A、B构成&#xff08;或者更多&#xff09;&#xff0c;任何其中一个字段都可能具有重复的数据。 需要只取字段A所有重复数据中的一条构成查询结果&#xff0c;也就是字段A取到所有的可能取值且无重复。 二. 方法一&#xff08;where ... …

Appium环境搭建,华为nova8鸿蒙系统(包括环境安装,环境配置)(一)

1.安装代码工具包 appium python client pip install appium-python-client 2.安装JDK 参考链接: ant+jmeter+jenkins从0实现持续集成(Windows)-CSDN博客 3.下载并安卓SDK 下载地址:AndroidDevTools - Android开发工具 Android SDK下载 Android Studio下载 Gradle下载…