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 ...
随机推荐
- 使用Python爬取、清洗并分析前程无忧的大数据职位
爬取前程无忧的数据(大数据职位) # -*- coding: utf-8 -*- """ Created on Wed Nov 1 14:47:27 2019 @auth ...
- Nginx源码构建
1.上传或下载nginx软件包,并解压 rz 2.搭建nginx安装环境 yum install gcc-c++ zlib-devel pcre-devel openssl-devel automak ...
- 使用 Flask 和 Vue.js 来构建全栈单页应用
在这个教程中,我将向你展示如何将 Vue 的单页面应用和 Flask 后端连接起来. 简单的来说,如果想在 Flask 中使用 Vue 框架是没有什么问题的. 但在实际中存在一个明显的问题就是 Fla ...
- SDWebImage学习之 NSCache
1.使用SDWebImage的好处 1.异步下载(避免主线程卡死) 2.做好图片缓存(这样就不需要每次都加载网络图片) 3.解决了循环利用的问题 很容易造成内存警告
- 谈一谈个人利用Java的mysql的知识完成的数据库的项目-----用户信息管理系统
首先,我先简述一下自己做的过程啊,相信大家来找这样的博客,也都是为了完成自己课程任务吧.我也一样是一名大一的学生,是为了自己的课程任务而开始做数据库的项目的.因为还没学mysql吗,所以是自己找视频啊 ...
- CSS自定义默认样式
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, ...
- 大型情感剧集Selenium:1_介绍 #华为云·寻找黑马程序员#
学习selenium能做什么? 很多书籍.文章中是这么定义selenium的: Selenium 是开源的自动化测试工具,它主要是用于Web 应用程序的自动化测试,不只局限于此,同时支持所有基于web ...
- eNSP 简介及基础操作
eNSP 一. eNSP简介 eNSP是一款由华为自主研发的.免费的.可扩展的.图形化操作的网络仿真工具平台,主要对企业网络路由器.交换机及相关物理设备进行软件仿真,支持大型网络模拟.界面如下: 界面 ...
- set容器
set容器简介: 1) set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按一定的顺序排列.元素插入过程是按排序规则插入,所以不能指定插入位置. 2) set采用红黑树变体的数据结构实现,红 ...
- kubernetes学习笔记(三)——利用kubeadm部署集群
文章目录 (一)安装前准备 (二)master安装 1.安装组件 2.排错 (三)node安装 1.安装组件 2.加入master 3.排错 (四)网络安装 (五)dashboard安装 (一)安装前 ...