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 ...
随机推荐
- hunnu--11545--小明的烦恼——找路径
小明的烦恼--找路径 Time Limit: 2000ms, Special Time Limit:5000ms, Memory Limit:32768KB Total submit users: ...
- java设计模式----复合模式
复合模式:复合模式结合两个或以上的模式,组成一个解决方案,解决一再发生的一般性问题 要点: 1.MVC是复合模式,结合了观察者模式.策略模式和组合模式 2.模型使用观察者模式,以便观察者更新,同时保持 ...
- ubuntu git ssh不通
xyh@ubuntu-64:~$ ssh -v git@danxinben.com ...
- Apache Qpid Broker云
一. 什么是Broker云 Apathe Qpid 支持Broker Federation ,也就是Broker联盟或者叫做Broker云.Broker Federation可以通过配置消息路 ...
- DRF之视图组件 三次封装
1.为什么要进行封装 1.1 在处理表的时候,如果有几十张表都需要增删改查查时,如果每一张表都写这些方法,会让代码显得冗余,所以需要将这些方法进行封装,然后不同的表都去继承这写方法.(这是思路) 1. ...
- SHOW PROCESSLIST Syntax
https://dev.mysql.com/doc/refman/5.7/en/show-processlist.html SHOW PROCESSLIST shows you which threa ...
- JSP 用poi 读取Excel
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- Java异步套接字实例
服务端 package com.test.server; import java.io.IOException; import java.net.InetSocketAddress; import j ...
- poj 1789 Truck History 解题报告
题目链接:http://poj.org/problem?id=1789 题目意思:给出 N 行,每行7个字符你,统计所有的 行 与 行 之间的差值(就是相同位置下字母不相同),一个位置不相同就为1,依 ...
- hdu 2066 一个人的旅行 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2066 题目意思:给出T条路,和草儿家相邻的城市编号,以及草儿想去的地方的编号.问从草儿家到达草儿想去的 ...