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 ...
随机推荐
- hdu 4858 项目管理(vector模拟)
# include <stdio.h> # include <algorithm> # include <string.h> # include <vecto ...
- 如何理解pca和svd的关系?
主成分分析和奇异值分解进行降维有何共同点? 矩阵的奇异值分解 当矩阵不是方阵,无法为其定义特征值与特征向量,可以用一个相似的概念来代替:奇异值. 通常用一种叫奇异值分解的算法来求取任意矩阵的奇异值: ...
- js之substr和substring的差别
今天有人在群里问这两个的差别,借这个机会在这罗列下 substring(from,to) 開始和结束的位置,从零開始的索引 參数 描写叙述 from 必需. 一个非负的整数,规定要提取 ...
- ZOJ 3874 Permutation Graph 分治NTT
Permutation Graph Time Limit: 2 Seconds Memory Limit: 65536 KB Edward has a permutation {a1, a2 ...
- 把node加入master节点时,日志内容分析
root@node1:~# kubeadm --token bggbum.mj3ogzhnm1wz07mj --discovery-token-ca-cert-hash sha256:8f02f833 ...
- Java中的常用异常处理方法
觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能够迅速找出异常处理的六个问题吗? 1 OutputStreamWriter out = ... 2 ...
- GitExtensions 官方手册(英文)
在线版本(最新版):https://git-extensions-documentation.readthedocs.io/en/latest/ PDF版本(版本号 2.48):http://pan. ...
- C、C++混合编程之extern "C"
为何要“混合编程”?举个例子: CHeader.h #ifndef C_HEADER_H #define C_HEADER_H void func(); #endif CHeader.c #inclu ...
- MTK平台下Battery驱动分析
主要涉及代码: Kernel: kernel-3.10\drivers\power\mediatek\ kernel-3.10\drivers\misc\mediatek\mach\mt6580\&l ...
- JSP 用poi 读取Excel
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...