请求的三种拦截汇总-filter,interceptor,filter

请求的三种拦截

需求:记录所有 API 的处理时间

  • 过滤器(Filter)

    自定义filter

    package com.fengxuechao.seed.security.web.filter;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    /**
     * @author fengxuechao
     * @date 2019-08-01
     */
    @Slf4j
    public class TimeFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            log.info("time filter init");
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            log.info("time filter start");
            long start = System.currentTimeMillis();
            chain.doFilter(request,response);
            log.info("time filter:{}ms", System.currentTimeMillis() - start);
            log.info("time filter finish");
        }
    
        @Override
        public void destroy() {
            log.info("time filter destroy");
        }
    }
    

    如何添加第三方 filter 到过滤器链中去?

    /**
     * @author fengxuechao
     * @date 2019-08-08
     */
    @Configuration
    public class WebConfig {
    
        /**
         * 第三方 filter 加载方式
         *
         * @return
         */
        @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;
        }
    }
    
  • 拦截器(Interceptor)

    /**
     * @author fengxuechao
     * @date 2019-08-01
     */
    @Slf4j
    @Component
    public class TimeInterceptor implements HandlerInterceptor {
    
        /**
         * 这个方法在控制器某个方法调用之前会被调用
         *
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         */
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            log.info("preHandle");
    
    //        log.info("处理器类名 {}", ((HandlerMethod) handler).getBean().getClass().getName());
    //        log.info("方法名 {}", ((HandlerMethod) handler).getMethod().getName());
    
            request.setAttribute("startTime", System.currentTimeMillis());
            return true;
        }
    
        /**
         * 在控制器某个方法调用之后会被调用
         * 如果控制器方法调用过程中产生异常,这个方法不会被调用
         *
         * @param request
         * @param response
         * @param handler
         * @param modelAndView
         * @throws Exception
         */
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                               ModelAndView modelAndView) throws Exception {
            log.info("postHandle");
            Long start = (Long) request.getAttribute("startTime");
            log.info("time interceptor 耗时:" + (System.currentTimeMillis() - start));
    
        }
    
        /**
         * 不管控制器方法正常调用或者抛出异常,这个方法都会被调用
         *
         * @param request
         * @param response
         * @param handler
         * @param ex
         * @throws Exception
         */
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            log.info("afterCompletion");
            Long start = (Long) request.getAttribute("startTime");
            log.info("time interceptor 耗时:" + (System.currentTimeMillis() - start));
            log.info("ex is " + ex);
    
        }
    
    }
    
    /**
     * @author fengxuechao
     * @date 2019-08-08
     */
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Autowired
        private TimeInterceptor timeInterceptor;
    
        /**
         * 添加 Spring 拦截器
         *
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(timeInterceptor);
        }
    }
    
  • 切片(Aspect)

    /**
     * @author fengxuechao
     * @date 2019-08-21
     */
    @Slf4j
    @Aspect
    @Component
    public class TimeAspect {
    
        /**
         * 使用@Arount 完全覆盖了 @Before,@After @AfterThrowing,所以一般使用 @Around
         *
         * @param pjp
         * @return
         * @throws Throwable
         */
        @Around("execution(* com.fengxuechao.seed.security.web.UserController.*(..))")
        public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {
    
            log.info("time aspect start");
    
            Object[] args = pjp.getArgs();
            for (Object arg : args) {
                log.info("arg is " + arg);
            }
    
            long start = System.currentTimeMillis();
    
            // 执行被被切(被拦截)的方法
            Object object = pjp.proceed();
    
            log.info("time aspect 耗时:" + (System.currentTimeMillis() - start));
    
            log.info("time aspect end");
    
            return object;
        }
    
    }
    

过滤器,拦截器,切片的拦截顺序
请求的三种拦截汇总-filter,interceptor,filter_第1张图片

你可能感兴趣的:(springboot)