springboot中使用Filter、Interceptor和aop拦截REST服务

在springboot中使用rest服务时,往往需要对controller层的请求进行拦截或者获取请求数据和返回数据,就需要过滤器、拦截器或者切片。

过滤器(Filter):对HttpServletRequest处理,也可以对HttpServletResponse 进行后处理,无法获取请求方法的信息。

拦截器(Interceptor):可以获取HttpServletRequest、HttpServletResponse的数据,也可以获取请求方法的信息,但是无法获取请求的参数和返回参数。

切片(Aspect):aop的切片可以获取请求的参数和返回的值,但是无法获取HttpServletRequest、HttpServletResponse的数据。

    1. 过滤器(Filter):
      @Component
      public class TimeFilter implements Filter {
        //销毁时
          @Override
          public void destroy() {
              System.out.println("time filter destroy");
          }
        //逻辑代码
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                  throws IOException, ServletException {
              System.out.println("time filter start");
              long start = new Date().getTime();
              chain.doFilter(request, response);
              System.out.println("time filter 耗时:"+ (new Date().getTime() - start));
              System.out.println("time filter finish");
          }
        //加载前
          @Override
          public void init(FilterConfig arg0) throws ServletException {
              System.out.println("time filter init");
          }
      
      }

      这样所有请求都能获取,如果过滤器没法加@Component定义为组件引用,可以在配置文件中引用

      @Configuration
      public class WebConfig extends WebMvcConfigurerAdapter {
          
          @Bean
          public FilterRegistrationBean timeFilter() {
              
              FilterRegistrationBean registrationBean = new FilterRegistrationBean();
              
              TimeFilter timeFilter = new TimeFilter();
              registrationBean.setFilter(timeFilter);
              
              List<String> urls = new ArrayList<>();
              urls.add("/*");//获取所有请求
              registrationBean.setUrlPatterns(urls);
              
              return registrationBean;
              
          }
      
      }
    2. 拦截器(Interceptor)
      @Component
      public class TimeInterceptor implements HandlerInterceptor {
        // 在业务处理器处理请求之前被调用
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                  throws Exception {
              System.out.println("preHandle");
              
              System.out.println(((HandlerMethod)handler).getBean().getClass().getName());
              System.out.println(((HandlerMethod)handler).getMethod().getName());
              
              request.setAttribute("startTime", new Date().getTime());
              return true;
          }
      // 在业务处理器处理请求完成之后,生成视图之前执行
          @Override
          public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                  ModelAndView modelAndView) throws Exception {
              System.out.println("postHandle");
              Long start = (Long) request.getAttribute("startTime");
              System.out.println("time interceptor 耗时:"+ (new Date().getTime() - start));
      
          }
        //请求完成之后
          @Override
          public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                  throws Exception {
              System.out.println("afterCompletion");
              Long start = (Long) request.getAttribute("startTime");
              System.out.println("time interceptor 耗时:"+ (new Date().getTime() - start));
              System.out.println("ex is "+ex);
      
          }
      
      }

      创建组件后需要在配置文件中定义下

      @Configuration
      public class WebConfig extends WebMvcConfigurerAdapter {
          
          @SuppressWarnings("unused")
          @Autowired
          private TimeInterceptor timeInterceptor;
          
          @Override
          public void addInterceptors(InterceptorRegistry registry) {
              registry.addInterceptor(timeInterceptor);
          }
      
      }
    3. 切片(Aspect)
      @Aspect
      @Component
      public class TimeAspect {
          
          @Around("execution(* com.project.web.controller.UserController.*(..))")
          public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
              
              System.out.println("time aspect start");
              
              Object[] args = pjp.getArgs();
              for (Object arg : args) {
                  System.out.println("arg is "+arg);//获取请求参数
              }
              
              long start = new Date().getTime();
              
              Object object = pjp.proceed();//获取返回值
              
              System.out.println("time aspect 耗时:"+ (new Date().getTime() - start));
              
              System.out.println("time aspect end");
              
              return object;
          }
      
      }

一个请求的处理顺序是过滤器(Filter)->拦截器(Interceptor)->切片(Aspect)

原文地址:https://www.cnblogs.com/dinghaoran/p/11851224.html