SpringMVC的Body参数拦截的问题

SpringMVC对出参和入参有非常友好的拓展支持,方便你对数据的输入和输出有更大的执行权,我们如何通过SpringMVC定义的结果做一系列处理呢?

入参

RequestBodyAdvice : 针对所有以@RequestBody的参数做处理

参考案例 : JsonViewRequestBodyAdvice

public class JsonViewRequestBodyAdvice extends RequestBodyAdviceAdapter {

  /**
   * 这里是一个前置拦截匹配操作,其实就是告诉你满足为true的才会执行下面的beforeBodyRead方法,这里可以定义自己业务相关的拦截匹配
   * @param methodParameter
   * @param targetType
   * @param converterType
   * @return
   */
  @Override
  public boolean supports(MethodParameter methodParameter, Type targetType,
      Class<? extends HttpMessageConverter<?>> converterType) {

    return (AbstractJackson2HttpMessageConverter.class.isAssignableFrom(converterType) &&
        methodParameter.getParameterAnnotation(JsonView.class) != null);
  }

    // 这里就是具体的前置操作了... 下面的例子就是查找这个入参方法是否有@JsonView修饰
  @Override
  public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter methodParameter,
      Type targetType, Class<? extends HttpMessageConverter<?>> selectedConverterType) throws IOException {

    JsonView annotation = methodParameter.getParameterAnnotation(JsonView.class);
    Class<?>[] classes = annotation.value();
    if (classes.length != 1) {
      throw new IllegalArgumentException(
          "@JsonView only supported for request body advice with exactly 1 class argument: " + methodParameter);
    }
    return new MappingJacksonInputMessage(inputMessage.getBody(), inputMessage.getHeaders(), classes[0]);
  }
}

出参

ResponseBodyAdvice: 针对所有以@ResponseBody的参数做处理

参考案例:

@ControllerAdvice
public class LogResponseBodyAdvice implements ResponseBodyAdvice {

  /**
   *
   * @param returnType
   * @param converterType
   * @return
   */
  @Override
  public boolean supports(MethodParameter returnType, Class converterType) {
    return true;
  }

  @Override
  public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
    // 做任何事情 body 就是返回的结果对象,没有处理之前
    return body;
  }
}

注意事项

自定义的处理对象类上必须得加上@ControllerAdvice注解!

为什么?

源码中RequestMappingHandlerAdapter类在执行initControllerAdviceCache()做初始化的时候会执行一个

List<ControllerAdviceBean> beans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
AnnotationAwareOrderComparator.sort(beans);

而ControllerAdviceBean.findAnnotatedBeans方法会查找类上有ControllerAdvice注解的类才会加入到处理当中..

public static List<ControllerAdviceBean> findAnnotatedBeans(ApplicationContext applicationContext) {
    List<ControllerAdviceBean> beans = new ArrayList<ControllerAdviceBean>();
    for (String name : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, Object.class)) {
      if (applicationContext.findAnnotationOnBean(name, ControllerAdvice.class) != null) {
        beans.add(new ControllerAdviceBean(name, applicationContext));
      }
    }
    return beans;
  }

所以大家可以根据自己的需要,定义结果的入参和出参结果做一些特殊处理.....

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • SpringMVC中的拦截器详解及代码示例

    本文研究的主要是SpringMVC中的拦截器的介绍及实例代码,配置等内容,具体如下. Springmvc的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理.本文主要总结一下springmvc中拦截器是如何定义的,以及测试拦截器的执行情况和使用方法. 1. springmvc拦截器的定义和配置 1.1 springmvc拦截器的定义 在springmvc中,定义拦截器要实现HandlerInterceptor接口,并实现该接口中提供的三个方法,如下: /

  • SpringMVC拦截器实现监听session是否过期详解

    本文主要向大家介绍了SpringMVC拦截器实现:当用户访问网站资源时,监听session是否过期的代码,具体如下: 一.拦截器配置 <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/user/login"/> <!-- 不拦截登录请求 --> <mvc:exclude-

  • Spring MVC实现的登录拦截器代码分享

    之前接触过struts拦截器,但是没有使用过Spring MVC拦截器,今天花了一天时间好好研究了一下. 本文首先介绍了拦截器的基本概念,然后向大家阐述拦截器与过滤器的简要区别,通过HandlerInterceptor 接口中定义的三个方法实现拦截器功能,最后介绍了配置相关的代码,接下来看看具体内容. 定义拦截器 SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor 来实现的.在SpringMVC 中定义一个Interceptor 非常简单,主要有两

  • SpringMVC拦截器实现单点登录

    单点登录的功能在实际的应用场景中还是很重要的,逻辑上我们也不允许一个用户同时在进行着两个操作,下面就来了解一下SpringMVC的单点登录实现 SpringMVC的拦截器不同于Spring的拦截器,SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet,所以只需要在DispatcherServlet上做文章即可,DispatcherServlet也没有代理,同时SpringMVC管理的Controller也不有代理. 1,先探究一个

  • Spring MVC拦截器_动力节点Java学院整理

    Spring为我们提供了: org.springframework.web.servlet.HandlerInterceptor接口, org.springframework.web.servlet.handler.HandlerInterceptorAdapter适配器, 实现这个接口或继承此类,可以非常方便的实现自己的拦截器. 有以下三个方法:  Action之前执行: public boolean preHandle(HttpServletRequest request, HttpServ

  • Springmvc中的转发重定向和拦截器的示例

    本文介绍了Springmvc中的转发重定向和拦截器的示例,分享给大家,具体如下: 可变参数在设计方法时,使用 数据类型... 来声明参数类型,例如: public static void function(int... numbers) 在实现方法体时,可变参数是作为数组来处理 public class Test{ public static void main(String[] args){ System.out.println(Test.sum(1,2,3)); System.out.pri

  • springMVC拦截器HandlerInterceptor用法代码示例

    摘要:很多时候我们都会去修改其他同事的bug,甚至是已经离职的同事的bug,有时候我们点击页面去不着到后台对应的是哪个controller,针对这个问题,其实我们可以通过sprngmvc的拦截器来拦击用户的请求从而知道页面请求的是哪个class的哪个方法,当然这些打印日志信息肯能并不适合放在生产环境,或者这个拦截器也是非必要的.... 一.HandlerInterceptor用法 第一步:注册拦截器 <!-- 注册拦截器 --> <mvc:interceptors> <bea

  • springmvc用于方法鉴权的注解拦截器的解决方案代码

    最近在用SpringMvc写项目的时候,遇到一个问题,就是方法的鉴权问题,这个问题弄了一天了终于解决了,下面看下解决方法 项目需求:需要鉴权的地方,我只需要打个标签即可,比如只有用户登录才可以进行的操作,一般情况下我们会在执行方法时先对用户的身份进项校验,这样无形中增加了非常大的工作量,重复造轮子,有了java注解只需要在需要鉴权的方法上面打个标签即可: 解决方案: 1.首先创建一个注解类: @Documented @Inherited @Target({ElementType.METHOD,E

  • springmvc限流拦截器的示例代码

    限流器算法 目前常用限流器算法为两种:令牌桶算法和漏桶算法,主要区别在于:漏桶算法能够强行限制请求速率,平滑突发请求,而令牌桶算法在限定平均速率的情况下,允许一定量的突发请求 下面是从网上找到的两张算法图示,就很容易区分这两种算法的特性了 漏桶算法 令牌桶算法 针对接口来说,一般会允许处理一定量突发请求,只要求限制平均速率,所以令牌桶算法更加常见. 令牌桶算法工具RateLimiter 目前本人常用的令牌桶算法实现类当属google guava的RateLimiter,guava不仅实现了令牌桶

  • 防止SpringMVC拦截器拦截js等静态资源文件的解决方法

    SpringMVC提供<mvc:resources>来设置静态资源,但是增加该设置如果采用通配符的方式增加拦截器的话仍然会被拦截器拦截,可采用如下方案进行解决: 方案一.拦截器中增加针对静态资源不进行过滤(涉及spring-mvc.xml) <mvc:resources location="/" mapping="/**/*.js"/> <mvc:resources location="/" mapping=&quo

  • 详解SpringMVC拦截器配置及使用方法

    本文介绍了SpringMVC拦截器配置及使用方法,分享给大家,具体如下: 常见应用场景 1.日志记录:记录请求信息的日志,以便进行信息监控.信息统计.计算PV(Page View)等. 2.权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面: 3.性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录): 4.通用行为:读取cookie得到用户信

随机推荐