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 ...
随机推荐
- NOI 2014简要题解
Day 1.Problem A. 起床困难综合症 100分做法: 把数字看成二进制数.对于初始攻击力.我们将其拆成32位,并求出每一位为0和1时经过全部防御门之后分别得到的数字.然后就是按位贪心了,我 ...
- NVIDIA---CUDA
http://en.wikipedia.org/wiki/CUDA CUDA From Wikipedia, the free encyclopedia CUDA Developer(s) N ...
- 龙书D3D11章节习题答案(第四章)
下面答案仅供參考,有错欢迎留言. Chapter 4:Direct3D Initialzation 1. Modify the previous exercise solution by dis ...
- android-custom-tab-with-viewpager
https://github.com/eltld/android-custom-tab-with-viewpager
- WPF数据验证(5)―― 错误模板
<Style TargetType="{x:Type TextBox}"> <Setter Property="Validatio ...
- Swift开发教程--怎样播放图片动画
废话少说,直接上代码: var barsAnim = UIImageView(frame: self.view.frame); barsAnim.animationImages = NSArray() ...
- CSS3 弹性盒子(Flex Box) 微信小程序图片通栏
{{define "chkUrl"}} <!DOCTYPE html><html lang="zh-cmn-Hans"><head ...
- SLG, 菱形格子的算法.(递归版
class GeoPoint{ public: int x; int y; public: bool operator == (const GeoPoint& p){ return p.x = ...
- Tomcat的虚拟主机的配置
比如:配置一个虚拟主机的名字是www.sina.com 1 改动window系统中的HOST文件[C:\WINDOWS\system32\drivers\etc\hosts] 127.0.0.1 ...
- oracle性能监控
https://blog.csdn.net/yangshangwei/article/details/52449489#监控事例的等待 https://blog.csdn.net/yangshangw ...