SpringMVC 自定义参数解析器.
一、简述
有没有想过像 @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 自定义参数解析器.的更多相关文章
- springmvc 源码分析(三) -- 自定义处理器映射器和自定义处理器适配器,以及自定义参数解析器 和错误跳转自定页面
测试环境搭建: 本次搭建是基于springboot来实现的,代码在码云的链接:https://gitee.com/yangxioahui/thymeleaf.git DispatcherServlet ...
- SpringBoot系列教程web篇之如何自定义参数解析器
title: 190831-SpringBoot系列教程web篇之如何自定义参数解析器 banner: /spring-blog/imgs/190831/logo.jpg tags: 请求参数 cat ...
- Spring自定义参数解析器
结合redis编写User自定义参数解析器UserArgumentResolver import javax.servlet.http.Cookie; import javax.servlet.htt ...
- SpringMVC自动封装List对象 —— 自定义参数解析器
前台传递的参数为集合对象时,后台Controller希望用一个List集合接收数据. 原生SpringMVC是不支持,Controller参数定义为List类型时,接收参数会报如下错误: org.sp ...
- SpringBoot自定义参数解析器
一.背景 平常经常用 @RequestParam注解来获取参数,然后想到我能不能写个自己注解获取请求的ip地址呢?就像这样 @IP String ip 二.分析 于是开始分析 @RequestPara ...
- 一步一步自定义SpringMVC参数解析器
随心所欲,自定义参数解析器绑定数据. 题图:from Zoommy 干货 SpringMVC解析器用于解析request请求参数并绑定数据到Controller的入参上. 自定义一个参数解析器需要实现 ...
- 自定义springmvc参数解析器
实现spring HandlerMethodArgumentResolver接口 通过使用@JsonArg自定义注解来解析json数据(通过fastjson的jsonPath),支持多个参数(@Req ...
- 自定义HandlerMethodArgumentResolver参数解析器和源码分析
在初学springmvc框架时,我就一直有一个疑问,为什么controller方法上竟然可以放这么多的参数,而且都能得到想要的对象,比如HttpServletRequest或HttpServletRe ...
- springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)
之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...
随机推荐
- C# 异步并发操作,只保留最后一次操作
在我们业务操作时,难免会有多次操作,我们期望什么结果呢? 绝大部分情况,应该是只需要最后一次操作的结果,其它操作应该无效. 自定义等待的任务类 1. 可等待的任务类 AwaitableTask: // ...
- WebGPU学习(三):MSAA
大家好,本文学习MSAA以及在WebGPU中的实现. 上一篇博文 WebGPU学习(二): 学习"绘制一个三角形"示例 下一篇博文 WebGPU学习(四):Alpha To Cov ...
- ThreadLocal快速了解一下
欢迎点赞阅读,一同学习交流,有疑问请留言 . GitHub上也有开源 JavaHouse 欢迎star 1 引入 在Java8里面,ThreadLocal 是一个泛型类.这个类可以提供线程变量.每个线 ...
- Spring IOC容器装配Bean_基于XML配置方式
开发所需jar包 实例化Bean的四种方式 1.无参数构造器 (最常用) <?xml version="1.0" encoding="UTF-8"?> ...
- 深入 .NET Core 基础 - 2:共享框架
深入 .NET Core 基础 - 2:共享框架 原文地址:https://natemcmaster.com/blog/2018/08/29/netcore-primitives-2/ 共享框架从 . ...
- 不止面试-JVM垃圾回收面试题详解
第一部分:面试题 本次分享我们将尝试回答以下问题: GC 是什么? 为什么要有 GC? 简单说一下java的垃圾回收机制. JVM的常见垃圾回收算法有哪些? 为什么要使用分代回收机制? 如何判断一个对 ...
- Flask 蓝图机制及应用
我们都知道 flask 是一个轻量级的 web 框架,相对于其他同类型框架更为灵活.轻便.安全且容易上手.开发者可以随意编写自己想要的项目结构,同时还有很多的第三方库供君选择.但是灵活的同时也带来了相 ...
- 曹工杂谈:Spring boot应用,自己动手用Netty替换底层Tomcat容器
前言 问:标题说的什么意思? 答:简单说,一个spring boot应用(我这里,版本升到2.1.7.Release了,没什么问题),默认使用了tomcat作为底层容器来接收和处理连接. 我这里,在依 ...
- MySQL必知必会(使用函数处理数据)
#文本处理函数 SELECT vend_name, Upper(vend_name) AS vend_name_upcase FROM vendors ORDER BY vend_name; SELE ...
- ZOJ 2112 Dynamic Rankings(树状数组+主席树)
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...