自定义springmvc参数解析器
实现spring HandlerMethodArgumentResolver接口
通过使用@JsonArg自定义注解来解析json数据(通过fastjson的jsonPath),支持多个参数(@RequestBody只支持单个参数)
自定义注解@JsonArg
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface JsonArg {
/**
* @see <a href="https://github.com/alibaba/fastjson/wiki/JSONPath">https://github.com/alibaba/fastjson/wiki/JSONPath</a>
*/
String value() default "";
}
参数解析器实现
@Slf4j
public class JsonPathArgumentResolver implements HandlerMethodArgumentResolver {
private static final String JSONBODYATTRIBUTE = "JSON_REQUEST_BODY";
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(JsonArg.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
String body = getRequestBody(webRequest);
String value = parameter.getParameterAnnotation(JsonArg.class).value();
if (StringUtils.isBlank(value)) {
value = parameter.getParameterName();
}
Object val = JSONPath.read(body, value);
if (log.isDebugEnabled()) {
log.debug("resolveArgument return class type:{}", val == null ? null : val.getClass().getName());
log.debug("value:{}", val);
}
if (val instanceof JSONObject) {
return JSON.parseObject(((JSONObject) val).toJSONString(), parameter.getParameterType());
}
if (val instanceof JSONArray) {
ParameterizedType genericParameterType = (ParameterizedType) parameter.getGenericParameterType();
// 泛型参数可能有多个,现在只处理了一个
Type[] actualTypeArguments = genericParameterType.getActualTypeArguments();
String typeName = actualTypeArguments[0].getTypeName();
return JSON.parseArray(((JSONArray) val).toJSONString(), Class.forName(typeName));
}
//TODO 未实现基本类型之间互相转换
return val;
}
private String getRequestBody(NativeWebRequest webRequest) {
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
String jsonBody = (String) servletRequest.getAttribute(JSONBODYATTRIBUTE);
if (jsonBody == null) {
try {
String body = IOUtils.toString(servletRequest.getInputStream(), StandardCharsets.UTF_8);
servletRequest.setAttribute(JSONBODYATTRIBUTE, body);
return body;
} catch (Exception e) {
log.error("read request body error:{}", e.getMessage());
throw new RuntimeException(e);
}
}
return jsonBody;
}
}
配置
自定义参数解析器优先级低于spring提供的默认解析器,会被默认解析器处理
@Configuration
@EnableWebMvc
// springboot 2.0实现 WebMvcConfigurer 接口
public class WebMvcConfigurer extends WebMvcConfigurerAdapter {
/**
* prioritize Custom ArgumentMethodHandlers
*/
@Autowired
public void prioritizeCustomArgumentMethodHandlers(RequestMappingHandlerAdapter adapter) {
List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<>(adapter.getArgumentResolvers());
List<HandlerMethodArgumentResolver> customResolvers = adapter.getCustomArgumentResolvers();
argumentResolvers.removeAll(customResolvers);
argumentResolvers.addAll(0, customResolvers);
adapter.setArgumentResolvers(argumentResolvers);
}
/**
* registry argumentResolvers
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new JsonPathArgumentResolver());
}
}
使用
@PostMapping("/test.do")
public void test(@JsonArg String name) {
log.debug("name:{}", name);
}
自定义springmvc参数解析器的更多相关文章
- 一步一步自定义SpringMVC参数解析器
随心所欲,自定义参数解析器绑定数据. 题图:from Zoommy 干货 SpringMVC解析器用于解析request请求参数并绑定数据到Controller的入参上. 自定义一个参数解析器需要实现 ...
- 自定义HandlerMethodArgumentResolver参数解析器和源码分析
在初学springmvc框架时,我就一直有一个疑问,为什么controller方法上竟然可以放这么多的参数,而且都能得到想要的对象,比如HttpServletRequest或HttpServletRe ...
- 实现自定义的参数解析器——HandlerMethodArgumentResolver
1.为什么需要自己实现参数解析器 我们都知道在有注解的接口方法中加上@RequestBody等注解,springMVC会自动的将消息体等地方的里面参数解析映射到请求的方法参数中. 如果我们想要的信息不 ...
- Spring boot中自定义Json参数解析器
转载请注明出处... 一.介绍 用过springMVC/spring boot的都清楚,在controller层接受参数,常用的都是两种接受方式,如下 /** * 请求路径 http://127.0. ...
- SpringMVC自动封装List对象 —— 自定义参数解析器
前台传递的参数为集合对象时,后台Controller希望用一个List集合接收数据. 原生SpringMVC是不支持,Controller参数定义为List类型时,接收参数会报如下错误: org.sp ...
- springmvc 源码分析(三) -- 自定义处理器映射器和自定义处理器适配器,以及自定义参数解析器 和错误跳转自定页面
测试环境搭建: 本次搭建是基于springboot来实现的,代码在码云的链接:https://gitee.com/yangxioahui/thymeleaf.git DispatcherServlet ...
- SpringMVC 自定义参数解析器.
一.简述 有没有想过像 @RequestParam.@RequestBody 这些注解的工作原理呢?为什么 form 表单.application/json 的参数能够直接封装进 Bean 对象中呢? ...
- SpringBoot系列教程web篇之如何自定义参数解析器
title: 190831-SpringBoot系列教程web篇之如何自定义参数解析器 banner: /spring-blog/imgs/190831/logo.jpg tags: 请求参数 cat ...
- springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)
之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...
随机推荐
- 性能库 Oracle数据库 连接不上问题的解决
今天性能库的centos 上面的oracle18c 数据库连接不上了 这里进行了一次简单处理 针对不同问题进行说明: 1. 实例时 blocked 的状态 问题现象: LSNRCTL> stat ...
- springMVC原理简单介绍
说明: 用户发送请求到DispatcherServlet,即前端控制器 DipatcherServlet调用处理器映射器HandlerMapping解析 处理器映射器HandlerMapping根据请 ...
- C++中的三种继承方式
1,被忽略的细节: 1,冒号( :)表示继承关系,Parent 表示被继承的类,public 的意义是什么? class Parent { }; class Child : public Parent ...
- [LeetCode] 227. 基本计算器 II
题目链接: https://leetcode-cn.com/problems/basic-calculator-ii 难度:中等 通过率:33.2% 题目描述: 实现一个基本的计算器来计算一个简单的字 ...
- 基于OneAPM的Web系统性能监测
1.在官网:http://www.oneapm.com/注册试用账号 2.选择AI,添加应用,下载安装本地探针程序(Agent) 3.在Tomcat中部署Web系统,并重启,然后在浏览器访问应用,稍等 ...
- cs244a-Introduction to Computer Networking-Unit2
Unit2: Transport 学习目标: how TCP set up a connection what TCP segment looks like how can TCP be in hig ...
- python3:tuple元组
https://www.runoob.com/python3/python3-tuple.html 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. Py ...
- C# wpf 使用资源文件 resx
随意新建一个wpf应用 在cs代码编辑,增加 using System.Resources; 放在最上 在方案新建文件夹 名 文件 在 文件 新建资源文件 资源.resx 资源.resx 添加字符串 ...
- 基于zynq XC7Z100 FMC接口通用计算平台 XC7Z100
一.板卡概述 本板卡基于Xilinx公司的FPGA XC7Z100 FFG 9000 芯片, 该平台为设计和验证应用程序提供了一个完整的开发平台.该平台使设计师能够更加简单进行高性能的原型设计,并 ...
- git 命令解析
git 补丁 Git 提供了两种补丁方案: (1)用 git diff 生成的UNIX标准补丁.diff文件:.diff文件只是记录文件改变的内容,不带有commit记录信息,多个commit可以 ...