解决Spring/SpringBoot @RequestParam注解无法读取application/json格式数据。

Emmmm…最近在做项目的途中,有遇到一个方法需要接收的参数只有一个或者较少的时候就懒得写实体类去接收,使用spring框架都知道,接收单个参数就使用@RequestParam注解就好了,但是前端对应的Content-type是需要改成application/x-www-form-urlencoded,所以在接口文档上面特地标记了。但是…不知道前端是格式改了但是参数还是用的json格式没有改成键值对的方式传递还是什么原因,就一直说参数传不过来,叫我改回json格式的。。我也实在是懒,另外一个也觉得没必要,就一两个参数就新建一个实体,太浪费,但是这个问题让我觉得不灵活蛮久了,也一直没找到办法,所以借这个机会,打开了我的开发神器,www.baidu.com…输入我的问题,找了好久也没找到有解决的方案,然后就想着看下Spring内部是怎么处理的吧,就稍微跟了下源码,下面就说下我解决的方案。

一、RequestMappingHandlerAdapter

RequestMappingHandlerAdapter实现了HandlerAdapter接口,顾名思义,表示handler的adapter,这里的handler指的是Spring处理具体请求的某个Controller的方法,也就是说HandlerAdapter指的是将当前请求适配到某个Handler的处理器。RequestMappingHandlerAdapter是HandlerAdapter的一个具体实现,主要用于将某个请求适配给@RequestMapping类型的Handler处理,这里面就包含着请求数据和响应数据的处理。

如果是想处理响应参数的话就使用

能获取到这个列表了,那需要加入我们自己定义的处理器应该不太麻烦了吧这里不讲返回数据的自定义策略处理, 上也有其他文章,如果需要可以找下)

二、HandlerMethodArgumentResolver

策略接口解决方法参数代入参数值在给定请求的上下文(翻译的源码注释)

三、RequestParamMethodArgumentResolver

四、MyHandlerMethodArgumentResolver

直接上代码吧

四、ConfigArgumentResolvers

自己的策略类已经写好了,那么怎么加入到配置中去呢/p>

/** * @BelongsProject:  * @BelongsPackage:  * @Author: hef * @CreateTime: 2020-06-20 18:49 * @Description: 描述 */@Configurationpublic class ConfigArgumentResolvers {    private final RequestMappingHandlerAdapter requestMappingHandlerAdapter;    public ConfigArgumentResolvers(RequestMappingHandlerAdapter requestMappingHandlerAdapter) {this.requestMappingHandlerAdapter = requestMappingHandlerAdapter;    }	//springBoot启动的时候执行    @PostConstruct    private void addArgumentResolvers() {// 获取到框架定义好的参数解析集合ListHandlerMethodArgumentResolver> argumentResolvers = requestMappingHandlerAdapter.getArgumentResolvers();MyHandlerMethodArgumentResolver myHandlerMethodArgumentResolver = getMyHandlerMethodArgumentResolver(argumentResolvers);// ha.getArgumentResolvers()获取到的是不可变的集合,所以我们需要新建一个集合来放置参数解析器ListHandlerMethodArgumentResolver> myArgumentResolvers = new ArrayList>(argumentResolvers.size() + 1);//这里有一个注意点就是自定义的处理器需要放在RequestParamMethodArgumentResolver前面//为什么呢为如果放在它后面的话,那么它已经处理掉了,就到不了我们自己定义的策略里面去了//所以直接把自定义的策略放在第一个,稳妥!// 将自定义的解析器,放置在第一个; 并保留原来的解析器myArgumentResolvers.add(myHandlerMethodArgumentResolver);myArgumentResolvers.addAll(argumentResolvers);//再把新的集合设置进去requestMappingHandlerAdapter.setArgumentResolvers(myArgumentResolvers);    }    /*** 获取MyHandlerMethodArgumentResolver实例*/    private MyHandlerMethodArgumentResolver getMyHandlerMethodArgumentResolver(    ListHandlerMethodArgumentResolver> argumentResolversList) {// 原本处理RequestParam的类RequestParamMethodArgumentResolver requestParamMethodArgumentResolver = null;if (argumentResolversList == null) {    throw new RuntimeException("argumentResolverList must not be null!");}for (HandlerMethodArgumentResolver argumentResolver : argumentResolversList) {    if (requestParamMethodArgumentResolver != null) { break;    }    if (argumentResolver instanceof RequestParamMethodArgumentResolver) {    // 因为在我们自己策略里面是还需要用到这个原本的类的,所以需要得到这个对象实例 requestParamMethodArgumentResolver = (RequestParamMethodArgumentResolver) argumentResolver;    

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年5月20日
下一篇 2020年5月20日

相关推荐