自定义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 ...
随机推荐
- 联盟周赛2019810 csgo (动态规划、不下降子序列)
今天起晚了...就做了俩题 难受的一批... 题目描述 著名第一人称射击游戏 csgo 因其优秀的平衡性,爽快的射击感和科学的战术配比赢得了世界广大玩家的好评. 在一局游戏中,分为两个阵营,他们的目标 ...
- 存储过程实例基于postgersql
数据库用的是postgersql 数据库管理工具是DBeaver mybatis操作数据库基于jdbcTemplate 1.写的存储方法放在数据库下面的Procedures目录下 function ...
- Python进阶编程 反射
1.7反射 python面向对象中的反射:通过字符串的形式操作对象相关的属性.python中的一切事物都是对象(都可以使用反射) class Foo: f = '类的静态变量' def __init_ ...
- mysql联合索引如何创建
例如: CREATE TABLE `test` ('aaa' varchar(16) NOT NULL default '', 'bbb' varchar(16) NOT NULL default ' ...
- vs2013在用户控件中添加jquery智能提示
一.在script文件夹下面添加_references.js文件夹 二.把jquery文件拖到该文件中 保存,重新打开相应的文件,即出现智能提示
- MySQL索引优化 笔记
少取字段,建立合理的索引 表优化: 1 定长与变长分离 如果都是定长 查询比较快 因为每一行的字节都是固定的 fixed 2 常用字段和不常用字段要分离 用户表 常用 放主表 个人介绍不常用 还比较长 ...
- 62. Unique Paths (JAVA)
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...
- 【TensorFlow探索之一】MNIST的初步尝试
最近在学习TensorFlow,尝试的第一个项目是MNIST.首先给出源码地址. 1 数据集的获取 我们可以直接运行下面的代码,来获取到MNIST的数据集. from tensorflow.examp ...
- ssh远程登录故障解决方案
问题描述: xshell远程连接服务器连接不上,如下图所示: 故障排除: . 首先查看自己系统的防火墙是否关闭,没有关闭的话关闭一下. # centos 7中关闭防火墙命令: systemctl st ...
- Linux学习--第十一天--source、环境变量目录、欢迎信息、正则、cut、awk、sed、sort、判断表达式、if、for、case、一些脚本
source source /root/.bashrc #让修改后的配置文件在不重启系统的情况下生效.source等同于. 环境变量目录 /etc/profile /etc/profile.d/*.s ...