过滤器(Filter)
Filter表示过滤器,是JavaWeb三大组件(Servlet、Filter、Listener)之一。
过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。(权限控制、统一编码处理、敏感字符处理等)
过滤器的配置:直接实现Filter 接口即可,重写里面的三个方法。在通过@WebFilter注解实现对特定URL拦截。
init() :该方法在容器启动初始化过滤器时被调用,它在 Filter 的整个生命周期只会被调用一次。注意:这个方法必须执行成功,否则过滤器会不起作用。
doFilter() :容器中的每一次请求都会调用该方法, FilterChain 用来调用下一个过滤器 Filter。
destroy(): 当容器销毁 过滤器实例时调用该方法,一般在方法中销毁或关闭资源,在过滤器 Filter 的整个生命周期也只会被调用一次。
@WebFilter("/*")//配置我们需要拦截的路径
public class FilterDemo implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//1.放行前对Request数据进行处理 这时response里面是没有数据的
System.out.println("FilterDemo...");
//放行
filterChain.doFilter(servletRequest,servletResponse);
//放行后对Response 数据处理
System.out.println("FilterDemo...");
}
@Override
public void destroy() {
}
}
执行逻辑是 先执行放行前的逻辑—>资源—>放行后的逻辑
拦截器(Interceptor)
拦截器它是链式调用,一个应用中可以同时存在多个拦截器Interceptor, 一个请求也可以触发多个拦截器 ,而每个拦截器的调用会依据它的声明顺序依次执行。
拦截器实现:
我们首先需要有一个拦截类,这个类要实现HandlerInterceptor接口,接口里面有三个方法:
public class Interceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return false;
// 在拦截点(Controller方法处理之前)执行拦截
//注意:如果该方法的返回值为false ,将视为当前请求结束,不仅自身的拦截器会失效,还会导致其他的拦截器也不再执行。
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 只有在 preHandle() 方法返回值为true 时才会执行。,在处理过程中(Controller方法处理完之后
// DispatcherServlet进行视图的渲染之前)执行拦截
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 只有在 preHandle() 方法返回值为true 时才会执行。在整个请求结束之后, DispatcherServlet 渲染了对应的视图之后执行。
// 在DispatcherServlet进行视图的渲染后 返回前进行拦截
}
}
还需要一个配置类实现WebMvcConfigurer,设置拦截路径和不拦截路径
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
//addPathPatterns()方法设置所有路径都被拦截
registry.addInterceptor(new Interceptor()).addPathPatterns("/**");
//excludePathPatterns()方法添加不拦截的路径
registry.addInterceptor(new Interceptor()).excludePathPatterns("/ready");
}
}
过滤器 和 拦截器 都体现了AOP的编程思想,都可以实现诸如日志记录、登录鉴权等功能。
触发时机
拦截器(Interceptor)是在Servlet和Controller控制器之间执行, 它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。拦截器是基于java的反射机制的。
而过滤器(Filter)是在请求进入Tomcat容器之后 但是在请求进入Servlet之前执行,也就是说过滤器Filter 的使用要依赖于Tomcat等容器,导致它只能在web程序中使用。过滤器是基于函数回调。