SpringBoot自定义参数解析器
一、背景
平常经常用 @RequestParam注解来获取参数,然后想到我能不能写个自己注解获取请求的ip地址呢?就像这样 @IP String ip
二、分析
于是开始分析 @RequestParam是如何实现的。
从@RequestParam注解开始入手,搜索该注解在源码中使用的地方
分别是类RequestParamMethodArgumentResolver和RequestParamMapMethodArgumentResolver


可以看到两个类都最终实现了HandlerMethodArgumentResolver这个接口。

里面就两个方法,supportsParameter方法是检测该参数是否支持这个参数解析器,
如果supportsParameter方法返回true,则调用resolveArgument来进行参数解析工作。
三、代码编写
现在就可以写自己的参数解析器了,但是推荐继承AbstractNamedValueMethodArgumentResolver而不是直接实现HandlerMethodArgumentResolver接口。
1.注解@IP
- /**
- * 获取参数
- * Created by 2YSP on 2019/1/6.
- */
- @Documented
- @Retention(value = RetentionPolicy.RUNTIME)
- @Target(ElementType.PARAMETER)
- public @interface IP {
- String name() default "ip";
- boolean required() default true;
- String defaultValue() default "0";
- }
2.参数解析器IPAddressArgumentResolver
- /**
- * Created by 2YSP on 2019/1/6.
- */
- public class IPAddressArgumentResolver extends AbstractNamedValueMethodArgumentResolver {
- @Override
- protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
- IP annotation = parameter.getParameterAnnotation(IP.class);
- return new IPAddressArgumentResolver.RequestIPNamedValueInfo(annotation);
- }
- @Nullable
- @Override
- protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
- HttpServletRequest servletRequest = request.getNativeRequest(HttpServletRequest.class);
- String ip = servletRequest.getRemoteAddr();
- return ip == null ? "127.0.0.1":ip;
- }
- @Override
- public boolean supportsParameter(MethodParameter parameter) {
- return parameter.hasParameterAnnotation(IP.class) && !Map.class.isAssignableFrom(parameter.nestedIfOptional().getNestedParameterType());
- }
- private static class RequestIPNamedValueInfo extends NamedValueInfo{
- private RequestIPNamedValueInfo(IP annotation) {
- super(annotation.name(), annotation.required(), annotation.defaultValue());
- }
- }
- }
这三个方法是必须实现的,还有一个可选重写的handleMissingValue。
3.添加配置
- @Configuration
- @EnableWebMvc
- public class MvcConfig implements WebMvcConfigurer {
- @Override
- public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
- resolvers.add(new IPAddressArgumentResolver());
- }
- }
4.controller
- @Slf4j
- @RestController
- public class VOTestController {
- @GetMapping("vo/test")
- public BaseVo test(@IP String ip){
- log.info("请求的ip地址为:{}",ip);
- BaseVo baseVo = new BaseVo();
- //设置为Null
- baseVo.setResult(null);
- return baseVo;
- }
- }
四、测试总结
启动项目,游览器请求http://localhost/vo/test可以看到日志显示:
2019-01-11 10:30:24.284 [http-nio-80-exec-3] INFO cn.sp.controller.VOTestController - 请求的ip地址为:0:0:0:0:0:0:0:1
代码已托管到我的github,点击访问,对@RequestParam实现原理感兴趣的童鞋可以自己看看源码。
SpringBoot自定义参数解析器的更多相关文章
- SpringBoot系列教程web篇之如何自定义参数解析器
title: 190831-SpringBoot系列教程web篇之如何自定义参数解析器 banner: /spring-blog/imgs/190831/logo.jpg tags: 请求参数 cat ...
- springmvc 源码分析(三) -- 自定义处理器映射器和自定义处理器适配器,以及自定义参数解析器 和错误跳转自定页面
测试环境搭建: 本次搭建是基于springboot来实现的,代码在码云的链接:https://gitee.com/yangxioahui/thymeleaf.git DispatcherServlet ...
- SpringMVC 自定义参数解析器.
一.简述 有没有想过像 @RequestParam.@RequestBody 这些注解的工作原理呢?为什么 form 表单.application/json 的参数能够直接封装进 Bean 对象中呢? ...
- Spring自定义参数解析器
结合redis编写User自定义参数解析器UserArgumentResolver import javax.servlet.http.Cookie; import javax.servlet.htt ...
- SpringMVC自动封装List对象 —— 自定义参数解析器
前台传递的参数为集合对象时,后台Controller希望用一个List集合接收数据. 原生SpringMVC是不支持,Controller参数定义为List类型时,接收参数会报如下错误: org.sp ...
- SpringBoot自定义参数验证器
前要 之前我们介绍了JSR-303验证方式,十分的方便Spring都帮我们封装好了,但是对一些复杂的验证,还是需要更加灵活的验证器的. JSR-303验证器传送门:https://www.jiansh ...
- 自定义springmvc参数解析器
实现spring HandlerMethodArgumentResolver接口 通过使用@JsonArg自定义注解来解析json数据(通过fastjson的jsonPath),支持多个参数(@Req ...
- 一步一步自定义SpringMVC参数解析器
随心所欲,自定义参数解析器绑定数据. 题图:from Zoommy 干货 SpringMVC解析器用于解析request请求参数并绑定数据到Controller的入参上. 自定义一个参数解析器需要实现 ...
- 自定义HandlerMethodArgumentResolver参数解析器和源码分析
在初学springmvc框架时,我就一直有一个疑问,为什么controller方法上竟然可以放这么多的参数,而且都能得到想要的对象,比如HttpServletRequest或HttpServletRe ...
随机推荐
- vs2017 使用GitHub 推送到远程仓储
vs2017下使用github拓展工具无法成功推送,提示“未能推送到远程存储库” 窗口错误显示:发布到远程存储库时遇到错误: Git failed with a fatal error. HttpRe ...
- SGU 194 Reactor Cooling 无源汇带上下界可行流
Reactor Cooling time limit per test: 0.5 sec. memory limit per test: 65536 KB input: standard output ...
- MYiSAM和InnoDB引擎区别(mysql)
MyISAM 1.读取速度快. 2.※更新时锁整个表. 3.占用资源少. 4.适合读多写少的业务. 5.※不支持事务. InnoDB 1.读取速度一般. 2.※更新时锁当前行. 3.占用资源高. ...
- Jmeter使用Http代理服务器报DNSName components must begin with a letter的错
最近了解到JMeter可以实现app的性能测试,需要借助JMeter的Http代理服务器来录制脚本. 于是,就按着网上的教程来进行操作,然而出师不利啊,刚启动就报错
- CarbonData
CarbonData http://carbondata.apache.org/ Apache顶级项目CarbonData应用实践与2.0新技术规划介绍_搜狐科技_搜狐网 https://www.so ...
- Joomla中的Task 和view 深入学习
[本文转自:梦溪笔记] Joomla 是一个优秀的CMS系统,她可以让你快速的完成一个网站的建设,她提供组件,模块,模板能够满足你大部分的网站需求.而组件在其中举足轻重. 一.基本知识 组件(comp ...
- safair 的css hack
在css里面使用[;attribute:value;] css参考如下: .header-share li{float: right; margin-left: 20px; [;width: 50px ...
- 使用RAID进行磁盘管理
转自http://www.linuxprobe.com/chapter-06/ 磁盘阵列(Redundant Arrays of Independent Disks,RAID),有“独立磁盘构成的具有 ...
- Python中的sort() key含义
sorted(iterable[, cmp[, key[, reverse]]]) iterable.sort(cmp[, key[, reverse]]) 参数解释: (1)iterable指定要排 ...
- golang copy函数
数组切片内容复制 转自:http://studygolang.com/articles/4560 用于将内容从一个数组切片复制到另一个数组切片.如果加入的两个数组切片不一样大,就会按其中较小的那个数组 ...