一、简述

有没有想过像 @RequestParam、@RequestBody 这些注解的工作原理呢?为什么 form 表单、application/json 的参数能够直接封装进 Bean 对象中呢?这就要说到 HandlerMethodArgumentResolver — 方法参数解析器,该接口有两个方法:

public interface HandlerMethodArgumentResolver {

	boolean supportsParameter(MethodParameter parameter);

	Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception; }

supportsParameter 方法返回 boolean 值,表示是否启用该解析器,true 表示启用,false 表示不启用;resolveArgument 方法表示方法参数的解析过程,就是你把 HTTP 的请求参数转换为方法参数的过程,返回 Object 对象,即参数的转换结果。

@RequestParam 对应的参数解析器是 RequestParamMethodArgumentResolver;@RequestBody 对应的参数解析器是 RequestResponseBodyMethodProcessor;诸如此类的解析器,读者可自行阅读。

二、自定义参数解析器

我想在控制器方法参数中得到当前用户的登陆信息,大概是如下这个效果,只要添加了 @CurrentUser 注解,那么 UserParam 参数中就会有当前用户的登陆信息。

    @RequestMapping(value = "/list", method = RequestMethod.POST)
public ResponseData<List<SysWayDto>> list(@CurrentUser UserParam userParam) {
Map<String, Object> objectMap = MapUtils.convertObjToMap(userParam);
return sysWayService.findWithOriginDest(objectMap);
}

怎么实现呢?首先我们需要有一个 @CurrentUser 注解:

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}

那么剩下来的工作就是 HandlerMethodArgumentResolver 的事情了:

@Slf4j
public class CurrentUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { /**
* 用于判定是否需要处理该参数分解,返回 true 为需要,并会去调用下面的方法resolveArgument。
*/
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType().isAssignableFrom(UserParam.class)
&& methodParameter.hasParameterAnnotation(CurrentUser.class);
} /**
* 真正用于处理参数分解的方法,返回的 Object 就是 controller 方法上的形参对象。
*/
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
String accessToken = nativeWebRequest.getHeader(GatewayHeader.accessToken);
try {
UserParam userParam = JsonUtils.readValue(JwtHelper.parseJWT(accessToken), UserParam.class);
return userParam ;
} catch (IOException e) {
log.error("CurrentUserHandlerMethodArgumentResolver resolveArgument readValue error.accessToken:{}", accessToken, e);
} catch (Exception e) {
log.error("CurrentUserHandlerMethodArgumentResolver resolveArgument error.accessToken:{}", accessToken, e);
}
return null;
}
}

最后,别忘了注册上自定义的参数解析器哦!

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter { @Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new CurrentUserHandlerMethodArgumentResolver());
}
}

SpringMVC 自定义参数解析器.的更多相关文章

  1. springmvc 源码分析(三) -- 自定义处理器映射器和自定义处理器适配器,以及自定义参数解析器 和错误跳转自定页面

    测试环境搭建: 本次搭建是基于springboot来实现的,代码在码云的链接:https://gitee.com/yangxioahui/thymeleaf.git DispatcherServlet ...

  2. SpringBoot系列教程web篇之如何自定义参数解析器

    title: 190831-SpringBoot系列教程web篇之如何自定义参数解析器 banner: /spring-blog/imgs/190831/logo.jpg tags: 请求参数 cat ...

  3. Spring自定义参数解析器

    结合redis编写User自定义参数解析器UserArgumentResolver import javax.servlet.http.Cookie; import javax.servlet.htt ...

  4. SpringMVC自动封装List对象 —— 自定义参数解析器

    前台传递的参数为集合对象时,后台Controller希望用一个List集合接收数据. 原生SpringMVC是不支持,Controller参数定义为List类型时,接收参数会报如下错误: org.sp ...

  5. SpringBoot自定义参数解析器

    一.背景 平常经常用 @RequestParam注解来获取参数,然后想到我能不能写个自己注解获取请求的ip地址呢?就像这样 @IP String ip 二.分析 于是开始分析 @RequestPara ...

  6. 一步一步自定义SpringMVC参数解析器

    随心所欲,自定义参数解析器绑定数据. 题图:from Zoommy 干货 SpringMVC解析器用于解析request请求参数并绑定数据到Controller的入参上. 自定义一个参数解析器需要实现 ...

  7. 自定义springmvc参数解析器

    实现spring HandlerMethodArgumentResolver接口 通过使用@JsonArg自定义注解来解析json数据(通过fastjson的jsonPath),支持多个参数(@Req ...

  8. 自定义HandlerMethodArgumentResolver参数解析器和源码分析

    在初学springmvc框架时,我就一直有一个疑问,为什么controller方法上竟然可以放这么多的参数,而且都能得到想要的对象,比如HttpServletRequest或HttpServletRe ...

  9. springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)

    之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...

随机推荐

  1. 程序员的算法课(20)-常用的图算法:最小生成树(MST)

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  2. 混淆矩阵-MATLAB代码详解

    一.混淆矩阵 (一).简介 在人工智能中,混淆矩阵(confusion matrix)是可视化工具,特别用于监督学习,在无监督学习一般叫做匹配矩阵.在图像精度评价中,主要用于比较分类结果和实际测得值, ...

  3. netty的调优-及-献上写过注释的源码工程

    Netty能干什么? Http服务器 使用Netty可以编写一个 Http服务器, 就像tomcat那样,能接受用户发送的http请求, , 只不过没有实现Servelt规范, 但是它也能解析携带的参 ...

  4. Python中的Tcp协议的应用之Tcp服务端程序开发

    TCP通信协议是面向连接的可靠的网络通信协议. 网络间想要进行数据传输必须要用到socket,socket翻译过来叫做套接字,其主要作用是不同设备或同一台设备之间的进程通信工具. Python中的Tc ...

  5. 每个开发人员都应该知道的11个Linux命令

    本文主要挑选出读者有必要首先学习的 11 个 Linux 命令,如果不熟悉的读者可以在虚拟机或云服务器上实操下,对于开发人员来说,能熟练掌握 Linux 做一些基本的操作是必要的! 事不宜迟,这里有 ...

  6. Java修炼——面向对象_抽象类和抽象方法

    抽象类和抽象方法 什么是抽象类? 使用 abstract 修饰的类称为抽象类 public abstract class Person { } 抽象类的特征 1) 抽象类不可以创建对象 2) 抽象类可 ...

  7. HDU2767 Proving Equivalences(加边变为强联通图)

    Proving Equivalences Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  8. elasticsearch中mapping全解实战

    目录 Mapping简介 Mapping Type 分词器最佳实践 字段类型 text 类型 keyword 类型 date类型 object类型 nest类型 range类型 实战:同时使用keyw ...

  9. 【重温基础】instanceof运算符

    最近开始在整理ES6/ES7/ES8/ES9的知识点(已经上传到 我的博客 上),碰到一些知识点是自己已经忘记(用得少的知识点),于是也重新复习了一遍. 这篇文章要复习的 instanceof 是我在 ...

  10. Robotframework常见问题收集

    一.Robotframework1.7.3控制台乱码处理 1.找到文件C:\Python37\Lib\site-packages\robotide\contrib\testrunner\testrun ...