拦截器与过滤器
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 来指定,值越小优先级越高