过滤器介绍
- 过滤器是基于AOP实现的用于对请求进行前置和后置处理的一种配置工具
- 过滤器是基于函数回调实现的
- 过滤器只能在web项目中使用,依赖servlet容易实现
- 过滤器几乎可以对任意请求进行过滤
过滤器的作用和分类
- 作用:
- 在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest 。据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据
- 在HttpServletResponse 到达客户端之前,拦截HttpServletResponse 。根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据
- 可以简单的理解,就是拦截HttpServletRequest和HttpServletResponse进行处理,合适的就放行,不合适的就拦截
- 分类:
- 用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求
- 日志Filter:详细记录某些特殊的用户请求
- 负责解码的Filter:包括对非标准编码的请求解码
- 能改变XML 内容的XSLTFilter等
过滤器的实现
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@Component
@WebFilter(urlPatterns = "/*")
public class TestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("过滤器:执行 init 方法。");
}
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
System.out.println("过滤器:开始执行 doFilter 方法。");
// 请求放行
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("过滤器:结束执行 doFilter 方法。");
}
@Override
public void destroy() {
System.out.println("过滤器:执行 destroy 方法。");
}
}
- 过滤器必须通过@Component交给Spring容器进行管理
- @WebFilter是用来设置哪些请求需要被拦截
- 要实现Filter接口,Filter接口中有三个方法需要集成,分别是init、doFilter和destory
- init():整个程序运行过程中只会调用一次,是实现对Filter对象的初始化,不用过分关注这个方法
- doFilter():过滤器的核心方法,过滤器核心功能在这个方法中实现,其中 FilterChain 参数是用来调用下一个过滤器或执行下一个流程
- destroy():用于Filter销毁前完成相关的资源回收工作
拦截器介绍
拦截器实现
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class TestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器:执行 preHandle 方法。");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器:执行 postHandle 方法。");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("拦截器:执行 afterCompletion 方法。");
}
}
- 可以看到拦截器和过滤器的实现非常的像,都实现了一个接口,也同样的都有三个方法要实现
- 同样的拦截器也必须要通过@Component注解交给Spring容器管理
- preHandle():在请求方法执行前调用,比如操作数据前必须验证用户的登录状态,验证通过返回true,继续执行数据操作业务,否则不执行。所以说实际上拦截器的切点是controller层中的方法
- postHandle():同样是拦截器的核心方法,完成第一个方法的验证之后,才会进到这一步,在请求之后渲染之前执行。
- afterHandle():会在整个请求结束之后再执行,也就是在 DispatcherServlet 渲染了对应的视图之后再执行
拦截器需要进行配置,配置如下
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class AppConfig implements WebMvcConfigurer {
// 注入拦截器
@Autowired
private TestInterceptor testInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(testInterceptor) // 添加拦截器
.addPathPatterns("/*"); // 拦截所有地址
}
}
过滤器和拦截器的区别
-
过滤器来自于Servlet相关的包,拦截器来自Spring框架的包
-
由上面一点就可以知道拦截器适用范围更加广,在支持Spring的项目中都可以应用,过滤器只适用于web项目
-
过滤器是基于回调函数实现的,在doFilter方法中需要调用doFilter进行下一个过滤器或流程的实现,拦截器则是基于反射实现的,也就是动态代理
-
执行的时间不同:执行顺序进入Tomcat容器->过滤器->Servlet->拦截器->控制器
-
实现功能不同
- 因为拦截器更接近业务系统,所以拦截器主要用来实现项目中的业务判断的,比如:登录判断、权限判断、日志记录等业务。 而过滤器通常是用来实现通用功能过滤的,比如:敏感词过滤、字符集编码设置、响应数据压缩等功能