zoukankan      html  css  js  c++  java
  • SpringBoot自定义参数解析器

    一、背景

    平常经常用 @RequestParam注解来获取参数,然后想到我能不能写个自己注解获取请求的ip地址呢?就像这样 @IP String ip

    二、分析

    于是开始分析 @RequestParam是如何实现的。

    从@RequestParam注解开始入手,搜索该注解在源码中使用的地方
    分别是类RequestParamMethodArgumentResolverRequestParamMapMethodArgumentResolver

    类关系图
    类关系图

    RequestParamMethodArgumentResolver
    RequestParamMethodArgumentResolver

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

    HandlerMethodArgumentResolver结构
    HandlerMethodArgumentResolver结构

    里面就两个方法,supportsParameter方法是检测该参数是否支持这个参数解析器,
    如果supportsParameter方法返回true,则调用resolveArgument来进行参数解析工作。

    三、代码编写

    现在就可以写自己的参数解析器了,但是推荐继承AbstractNamedValueMethodArgumentResolver而不是直接实现HandlerMethodArgumentResolver接口。
    1.注解@IP

    1. /** 
    2. * 获取参数 
    3. * Created by 2YSP on 2019/1/6. 
    4. */ 
    5. @Documented 
    6. @Retention(value = RetentionPolicy.RUNTIME) 
    7. @Target(ElementType.PARAMETER) 
    8. public @interface IP { 
    9.  
    10. String name() default "ip"
    11.  
    12. boolean required() default true
    13.  
    14. String defaultValue() default "0"

    2.参数解析器IPAddressArgumentResolver

    1. /** 
    2. * Created by 2YSP on 2019/1/6. 
    3. */ 
    4. public class IPAddressArgumentResolver extends AbstractNamedValueMethodArgumentResolver
    5. @Override 
    6. protected NamedValueInfo createNamedValueInfo(MethodParameter parameter)
    7. IP annotation = parameter.getParameterAnnotation(IP.class); 
    8. return new IPAddressArgumentResolver.RequestIPNamedValueInfo(annotation); 
    9.  
    10. @Nullable 
    11. @Override 
    12. protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception
    13. HttpServletRequest servletRequest = request.getNativeRequest(HttpServletRequest.class); 
    14. String ip = servletRequest.getRemoteAddr(); 
    15. return ip == null ? "127.0.0.1":ip; 
    16.  
    17. @Override 
    18. public boolean supportsParameter(MethodParameter parameter)
    19. return parameter.hasParameterAnnotation(IP.class) && !Map.class.isAssignableFrom(parameter.nestedIfOptional().getNestedParameterType()); 
    20.  
    21. private static class RequestIPNamedValueInfo extends NamedValueInfo
    22.  
    23. private RequestIPNamedValueInfo(IP annotation)
    24. super(annotation.name(), annotation.required(), annotation.defaultValue()); 
    25.  

    这三个方法是必须实现的,还有一个可选重写的handleMissingValue。
    3.添加配置

    1. @Configuration 
    2. @EnableWebMvc 
    3. public class MvcConfig implements WebMvcConfigurer
    4.  
    5.  
    6. @Override 
    7. public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers)
    8. resolvers.add(new IPAddressArgumentResolver()); 

    4.controller

    1. @Slf4j 
    2. @RestController 
    3. public class VOTestController
    4.  
    5. @GetMapping("vo/test"
    6. public BaseVo test(@IP String ip)
    7.  
    8. log.info("请求的ip地址为:{}",ip); 
    9. BaseVo baseVo = new BaseVo(); 
    10. //设置为Null 
    11. baseVo.setResult(null); 
    12. 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实现原理感兴趣的童鞋可以自己看看源码。

  • 相关阅读:
    Git库搭建好之后,当要提交一个新的文件,需要做的是3个步骤
    实习生面试经历
    Word2007中插入公式之后,公式上下有很大的空白
    参考文献规范格式
    Git学习笔记四--远程仓库
    Git学习笔记三--管理修改、撤销修改、删除文件
    Git学习笔记二--工作区和暂存区
    Git学习笔记一--创建版本库、添加文件、提交文件等
    Errors running builder 'DeploymentBuilder' on project '工程名'
    java中运算符与表达式
  • 原文地址:https://www.cnblogs.com/2YSP/p/10253927.html
Copyright © 2011-2022 走看看