1. 概述
在本文中,我们将比较 Java servlet Filter 和 Spring MVC HandlerInterceptor , 以及何时其中一个可能优于另一个。
2. 过滤器
过滤器是 Web 服务器的一部分,而不是 Spring 框架的一部分。 对于传入请求, 我们可以使用过滤器来操纵甚至阻止请求到达任何servlet 。反之亦然,我们也可以阻止响应到达客户端。
Spring Security是使用过滤器进行身份验证和授权的一个很好的例子。要配置 Spring Security,我们只需添加一个过滤器 DelegatingFilterProxy 。 Spring Security 然后可以拦截所有传入和传出流量。这就是为什么 Spring Security 可以在Spring MVC之外使用。
2.1.创建 过滤器
要创建过滤器,首先,我们创建一个实现 javax.servlet.Filter接口的 类:
@Component
public class LogFilter implements Filter {
private Logger logger = LoggerFactory.getLogger(LogFilter.class);
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
logger.info("Hello from: " + request.getLocalAddr());
chain.doFilter(request, response);
}
}
接下来,我们重写 doFilter 方法,在该方法中我们可以访问或操作 ServletRequest 、 ServletResponse 或 FilterChain 对象。我们可以使用 FilterChain 对象允许或阻止请求。
最后,我们通过使用 @Component 注解将 Filter 添加到 Spring 上下文中 。 春天将完成剩下的工作。
3.HandlerInterceptor
** HandlerInterceptor 是 Spring MVC 框架的一部分,位于 DispatcherServlet 和我们的 Controller 之间。** 我们可以在请求到达控制器之前以及视图渲染之前和之后拦截请求。
3.1.创建一个 HandlerInterceptor
为了创建 HandlerInterceptor ,我们创建一个实现 org.springframework.web.servlet.HandlerInterceptor 接口的类。这使我们可以选择重写三种方法:
- preHandle() – 在调用目标处理程序之前执行
- postHandle() – 在目标处理程序之后但在 DispatcherServlet 呈现视图之前执行
- afterCompletion() – 请求处理和视图渲染完成后的回调
让我们向测试拦截器中的三个方法添加日志记录:
public class LogInterceptor implements HandlerInterceptor {
private Logger logger = LoggerFactory.getLogger(LogInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
logger.info("preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
logger.info("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
logger.info("afterCompletion");
}
}
4. 主要差异和用例
让我们看一个图表,显示 Filter 和 HandlerInterceptor 在请求/响应流中的位置:
过滤器在请求到达 DispatcherServlet 之前拦截请求,这使得它们非常适合粗粒度任务, 例如:
- 验证
- 日志记录和审计
- 图像和数据压缩
- 我们希望与 Spring MVC 解耦的任何功能
另一方面, HandlerIntercepor 拦截 DispatcherServlet 和我们的 Controller 之间的请求。 这是在 Spring MVC 框架内完成的,提供对 Handler 和 ModelAndView 对象的访问。这减少了重复并允许更细粒度的功能,例如:
- 处理横切问题,例如应用程序日志记录
- 详细的授权检查
- 操作 Spring 上下文或模型
5. 结论
在本文中,我们介绍了 Filter 和 HandlerInterceptor 之间的差异。
* 关键要点是,使用 Filter ,我们可以在请求到达我们的控制器之前以及 Spring MVC 之外对其进行操作。 * 否则, HandlerInterceptor 是处理特定于应用程序的横切关注点的好地方。通过提供对目标 Handler 和 ModelAndView 对象的访问,我们可以进行更细粒度的控制。
所有这些示例和代码片段的实现都可以在 GitHub 上找到。