SpringMVC中的HandlerInterceptor与Filter

2023/05/12

1. 概述

在本文中,我们将比较Java Servlet Filter和Spring MVC HandlerInterceptor,以及何时可能比另一个更好。

2. Filters

过滤器是Web服务器的一部分,而不是Spring框架。对于传入的请求,我们可以使用过滤器来操纵甚至阻止请求到达任何Servlet,反之亦然,我们也可以阻止响应到达客户端。

Spring Security是使用过滤器进行身份验证和授权的一个很好的例子,要配置Spring Security,我们只需添加一个过滤器,DelegatingFilterProxy,然后Spring Security可以拦截所有传入和传出的流量,这就是为什么可以在Spring MVC之外使用Spring Security的原因。

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上下文中,Spring会完成剩下的工作。

3. HandlerInterceptors

HandlerInterceptor是Spring MVC框架的一部分,位于DispatcherServlet和我们的Controller之间,我们可以在请求到达我们的控制器之前,以及呈现视图之前和之后拦截请求。

3.1 创建一个处理程序拦截器

要创建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分离的任何功能

另一方面,HandlerInterceptor拦截DispatcherServlet和我们的Controller之间的请求,这是在Spring MVC框架内完成的,提供对Handler和ModelAndView对象的访问。这减少了重复并允许更细粒度的功能,例如:

  • 处理横切关注点,例如应用程序日志记录
  • 详细的授权检查
  • 操纵Spring上下文或模型

5. 总结

在本文中,我们介绍了Filter和HandlerInterceptor之间的区别。

关键要点是,使用Filters,我们可以在请求到达我们的控制器之前以及在Spring MVC之外对其进行操作。否则,HandlerInterceptor是处理特定于应用程序的横切关注点的好地方。通过提供对目标Handler和ModelAndView对象的访问,我们可以进行更细粒度的控制。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章