拦截器与过滤器

spring boot 实现自定义拦截器

1.自定义拦截器实现 HandlerInterceptor

public class MyHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("[1]执行 preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("[1]执行 postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("[1]执行 afterCompletion");
    }
}

2.编写配置类,继承WebMvcConfig ,并重写 addInterceptors 方法

@Configuration
public class MyWebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyHandlerInterceptor())
                .addPathPatterns("/user/*")
                .excludePathPatterns("/role/*");
    }
}

拦截器: 动态拦截 action 调用对象,提供一种机制,可以适开发者可以在 action 前后各执行一段代码,也可以在 action 前阻断执行。提供了一种提取action 重用代码的方式

拦截器大部分都是通过动态代理来实现的,拦截器是 AOP 的一种实现

使用拦截器

拦截器的方法执行顺序:

preHandle > action方法 > postHandle > afterCompletion 

1. 如果 preHandle 返回 false ,则后续的都不执行

2.若 preHandle 为 true ,则后续都会执行,但是当 action 方法抛出异常,则不执行 postHandle 

定义读个拦截器 

定义多个拦截器,可以通过 @Order(数子) 指定执行顺序,值越小优先级越高

1.所有的拦截器的 preHandle 都是在 action 之前执行

2.任意一个拦截器 preHandle 为 false ,则方法以及后续都不执行

3.例外情况,优先级最高的 preHandle 不是 false ,则只有该拦截器会执行 afterCompletion

4. 如果优先级最高的 preHandle 为 false ,则其他的所有拦截器都不执行 preHandle

spring boot 自定义过滤器实现

1.自定义过滤器,继承 Filter 并重写 doFilter

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        long startTime = System.currentTimeMillis();
        chain.doFilter(request,response);
        long end = System.currentTimeMillis();
        System.out.println("请求耗时:"+(end-startTime));
    }

    @Override
    public void destroy() {

    }
}

2.注册该 Filter

@Configuration
public class MyFilter2 {
    @Bean
    public FilterRegistrationBean regist(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new MyFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setName("myFilter");
        filterRegistrationBean.setOrder(1);
        return  filterRegistrationBean;
    }
}

过滤器+拦截器执行顺序: 

doFilter(进入)  - preHandle -执行action方法 - postHandle - afterCompletion - doFilter (出)

过滤器的第二种实现

@WebFilter(urlPatterns = "/*",filterName = "myFilter")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("Filter init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("Filter 方法前");
        long startTime = System.currentTimeMillis();
        chain.doFilter(request,response);
        long end = System.currentTimeMillis();
        System.out.println("请求耗时:"+(end-startTime));
        System.out.println("Filter 方法后");
    }

    @Override
    public void destroy() {
        System.out.println("Filter destroy");
    }
}

过滤器与拦截器都是 AOP 的一种具体实现,Filter 过滤器属于Servlet  ,而拦截器是独立存在的,其实现方式也不一样

过滤器是通过servlet 容器回调实现的,拦截器是通过动态代理来实现

定义多个Filter 与 Interceptor

Filter 之间 以及Interceptor 之间的基本顺序不变,其内部顺序可以通过 @Order 来指定,值越小优先级越高

 

posted @ 2020-08-13 15:06  byebai95  阅读(262)  评论(0编辑  收藏  举报