参数处理器(ArgumentResolvers)和返回参数处理器(ReturnValueHandlers)

在我们调用controller层组件时,Springboot实际上是使用代理模式进行调用,springmvc定义了一个DispatcherServlet实现HttpServlet方法,通过DispatcherServlet的doservice()方法处理请求,在doservice方法中,springboot先根据请求的request对象生成包含对应处理此请求的必要信息的对象mapperHandler,再根据mapperHandler对象生成实际处理请求的HandlerAdapter对象,调用HandlerAdapter的handle方法真正对请求进行处理,在执行我们实际定义的处理方法代码之前和之后,HandlerAdapter会调用一些代理增强,其中就包括根据我们方法的定义来选择合适的参数处理器来将请求中的参数封装成一个个对象,拿到对象后再通过反射使用处理好的参数执行我们定义好的Controller层处理逻辑,同理在执行完实际方法之后,在选择合适的返回值处理器真正处理返回。

WebMvcConfigurationSupport这个配置类中配置了springboot默认的各种处理器

自定义处理器

对于***自定义的参数处理器,springboot提供了一个HandlerMethodArgumentResolver接口。***

自定义返回参数处理器springboot提供了一个HandlerMethodReturnValueHandler接口

通过实现上述两个接口,我们可以实现自己的自定义处理器。

springboot也有一个名为AbstractMessageConverterMethodProcessor的抽象类,这个抽象类实现了上述两个参数处理器接口和返回参数处理器接口,我们可以直接继承AbstractMessageConverterMethodProcessor抽象类重写相关方法同时实现参数处理器和返回值处理器。

  • 需要注意的是,Spring有许多默认的参数处理器,在springboot底层调用时,所有的处理器都存储在一个list集合中,使用一个for循环进行调用,谁先被循环到符合条件就调用谁,暂未找到去除自带方法处理器的方法,最好是自己定义一个注解进行标识,从而百分百生效。
  • 下面我们实现一个自定义的处理器。

自定义一个注解进行标识:

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnocation {}

自定义一个方法处理器

@Component
public class MyProcesser extends AbstractMessageConverterMethodProcessor {protected MyProcesser(List<HttpMessageConverter<?>> converters) {super(converters);}@Overridepublic boolean supportsParameter(MethodParameter parameter) {return parameter.hasParameterAnnotation(MyAnnocation.class);}@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {Bean1 bean1 = new Bean1();bean1.setName("hello world");return bean1;}//如果返回是Bean1类型就支持处理@Overridepublic boolean supportsReturnType(MethodParameter returnType) {return returnType.getMethod().getReturnType().equals(Bean1.class);}@Overridepublic void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {//这里是摘抄springboot默认的RequestResponseBodyMethodProcessor处理器直接返回json对象。mavContainer.setRequestHandled(true);ServletServerHttpRequest inputMessage = createInputMessage(webRequest);ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);System.out.println("my handleReturnValue");// Try even with null return value. ResponseBodyAdvice could get involved.writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);}
}

添加这个处理器到容器中

@Configuration
public class WebConfigure implements WebMvcConfigurer {private final MyProcesser myProcesser;public WebConfigure(MyProcesser myProcesser) {this.myProcesser = myProcesser;}@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {resolvers.add(myProcesser);}@Overridepublic void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {handlers.add(myProcesser);}
}

测试类

//注意这里不要直接使用RestController注解,那样的话等同于在方法前加@ResponseBody,在遍历处理器时,默认处理@ResponseBody的处理
//器RequestResponseProcesser顺序可能在我们自定义的处理器之前从而导致无法调用我们自定义的处理器。
@Controller
public class TestController {@GetMapping("/test")public Bean1 test(@MyAnnocation Bean1 bean) {return bean;}
}

springboot自定义参数处理器和返回值处理器相关推荐

  1. springboot 自定义返回值处理器HandlerMethodReturnValueHandler

    WEB开发中有这样的需求: 返回给前台的数据需要有统一格式.但是在controller的每个mapping中手写包装很是麻烦,所以可以自定义返回值处理器进行结果包装. 文章目录 返回给前台的消息格式 ...

  2. .net mvc actionresult 返回字符串_072-SpringMVC后端控制器接收参数、处理器方法返回值类型、拦截器、文件上传下载...

    1. 注解式开发之annotation-driven解释 (1) mvc注解驱动在哪个文件中配置? 在springmvc中配置 (2) 配置mvc注解驱动使用哪个标签? 2. 注解式开发之视图解析器 ...

  3. Spring MVC 执行过程原理(请求映射原理、参数处理原理、返回值处理器)

    Spring MVC 执行过程分析 文章目录 Spring MVC 执行过程分析 请求映射原理 适配器Adapter 执行目标方法 参数处理器解析器HandlerMethodArgumentResol ...

  4. 函数参数和函数返回值

    函数参数和函数返回值 函数参数 思考一个问题,如下: 现在需要定义一个函数,这个函数能够完成2个数的加法运算,并且把结果打印出来,该怎样设计?下面的代码可以吗?有什么缺陷吗? def add2num( ...

  5. 引用参数与引用返回值

    原帖地址:http://www.cnblogs.com/bigshow/archive/2008/11/10/1330514.html 经常看到这样的声明:T& func(T& t), ...

  6. python函数定义参数类型和返回值类型

    python中我们也可以定义函数的参数类型和返回值类型,如下代码 #函数参数和返回值的类型声明,python函数类型的声明,更加有意义,更加实用一些 def add(a,b):''':param a: ...

  7. Java学习第十二天----方法参数类型以及返回值类型问题、链式编程、package包、权限修饰符、内部类、成员内部类

    Java学习第十二天----方法参数类型以及返回值类型问题.链式编程.package包.权限修饰符.内部类.成员内部类 1.方法参数类型: (1)类名作为形式参数: public class MyTe ...

  8. typeScript学习(九)、function_type_参数限制_返回值类型

    // let greet: Function; // // greet = (name: string): void => {// console.log(`hello ${name}`); / ...

  9. 实现 fizzBuzz 函数,参数 Thum 与返回值的关系如下: 1、如果 Thum 能同时被 3 和 5 整除,返回字符串 fizzbuzz 2、如果 Thum 能被 3 整除,返回字符串 fiz

    题目描述 实现 fizzBuzz 函数,参数 Thum 与返回值的关系如下: 1.如果 Thum 能同时被 3 和 5 整除,返回字符串 fizzbuzz 2.如果 Thum 能被 3 整除,返回字符 ...

最新文章

  1. python多线程输出_Python多线程
  2. 登录功能(token)
  3. Oracle statspack 基本使用
  4. .NET Core 小程序开发零基础系列(2)——小程序服务通知(模板消息)
  5. C/C++ 文件的后缀名
  6. [解决方案]ln:无法创建符号链接‘ /usr/bin/python‘:权限不够
  7. 小程序入门学习09--云开发02
  8. 在设备上添加项目失败_使用VisualGDB将Keil项目导入VisualStudio
  9. 【经验之谈】劝退文|听说你要转AI
  10. RAC以及ASM安装全过程整理
  11. mbr linux安装分区,linux – 在MBR扇区上安装GRUB或在启动分区上安装第一个扇区之间的区别?...
  12. 整理OpenResty+Mysql+Tomcat+JFinal+Cannal+HUI
  13. 最好的MATLAB入门教程
  14. 最新幸运盒子幸运砸金蛋微信盲盒游戏源码
  15. Redis主从复制-Replication
  16. java计算机毕业设计银创科技有限公司人事信息系统源码+数据库+系统+lw文档+部署
  17. vue安装postcss-pxtorem报错
  18. Sentinel_LDK linux加密使用
  19. html之行间样式和外部样式以及内部样式
  20. 朴素贝叶斯算法(python 实现)

热门文章

  1. 性能测试常用指标计算汇总
  2. 常见Linux运维面试题分享
  3. Surge:分子生成最前沿
  4. Oracle 表分区详解(partition table)
  5. office便捷办公03:Excel的vlookup和hlookup函数使用总结
  6. 用户需求和产品发展相互促进的关系初探
  7. JPA:LEFT JOIN 在hql语句中使用
  8. 「Python海龟画图」利用海龟画笔绘制简易雪人
  9. kitti深度图补全
  10. nginx服务器管理脚本