过滤器
过滤器只需要实现filter接口就可以使用或者通过@WebFilter注解就可以使用
主要包含以下三个方法
1)init(),容器启动时,过滤器会初始化且只初始化一次,这个方法必须成功,不然后续无法使用
2)doFilter,调用容器中的每一次请求都会调用该方法
3)destory(),当容器消息时,过滤器会调用这个方法,可以用来关闭资源,这个方法也只会被调用一次
Component
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println(Filter 前置);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println(Filter 处理中);
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println(Filter 后置);
}
}
拦截器
拦截器是链式调用,一个应用可以同时存在多个拦截器,一个请求可以触发多个拦截器
当存在多个拦截器时会依据声明的顺序执行
public void addInterceptors(InterceptorRegistry registry) {
// 对除静态资源外所有路径进行拦截
registry.addInterceptor(loginTicketInterceptor)
.excludePathPatterns("/css/**", "/js/**", "/img/**", "/editor-md/**");
registry.addInterceptor(messageInterceptor)
.excludePathPatterns("/css/**", "/js/**", "/img/**", "/editor-md/**");
registry.addInterceptor(dataInterceptor)
.excludePathPatterns("/css/**", "/js/**", "/img/**", "/editor-md/**");
}
拦截器一般是实现HandlerInterceptor接口,该接口定义了三个方法
1)preHandle(),这个方法在请求处理之前调用,这个方法返回值是true或者false,当是false时,会导致请求不再往下执行
2)postHandle(),这个方法在preHandle返回值为true才会执行,业务逻辑执行结束,渲染视图之前执行
这个方法执行顺序跟preHandle顺序是相反的,先声明的拦截器preHandle方法先执行,而它的postHandle反而会后执行
3)afterCompltion(),只有在preHandle返回值为true才会执行,在整个请求结束之后,视图渲染之后执行
二者的区别
1)原理不同
过滤器是基于函数回调的,每次过滤完毕后会执行dofilter操作,而该操作是回调接口FilterChain里的一个回调方法
而拦截器是基于动态代理来实现的
2)使用范围不同
过滤器是在servlet中定义的,也就是filter是依赖于tomcat等web容器的,导致它只能在web容器中使用
而拦截器是一个spring组件,因此它不仅能在web容器中使用,在其他应用程序也能使用
3)触发时期不同
过滤器是请求在进入容器后,在进入servlet之前执行的
而拦截器是在请求进入servlet之后在进入controller之前执行的