• 过滤器和拦截器的区别


    原文链接:过滤器和拦截器的区别 – 编程屋

    目录

    1 前言

    2 区别

    2.1  实现原理不同

    2.2 使用范围不同

    2.3 执行顺序不同

    4 注入Bean的情况不同

    1 前言

            可能有些小伙伴们在接手公司的项目时,经常看到公司的项目中既有过滤器又有拦截器,那么它们既然都拦截的作用,那么各自扮演着什么样的角色呢?要想搞懂它们所扮演的角色,就需要搞懂它们各自有什么作用了。

    2 区别

    2.1  实现原理不同

    1. 拦截器是基于java的反射机制,而过滤器是基于函数回调的。

    2. 拦截器只能对action请求请作用,而过滤器对所有的请求都起作用

    3. 拦截器可以访问action的上下文,而过滤器不能

    4 在action的生命周期中,拦截器可以多次被调用,而过滤器只能调用一次

    以下附有拦截器和过滤器的详细介绍:

    java过滤器(Filter)_IT盛夏的果实的博客-CSDN博客

    一篇搞懂拦截器(HandlerInterceptor)的用法_IT盛夏的果实的博客-CSDN博客

    2.2 使用范围不同

     可见Filter过滤器是javax.servlet包下的,是在Servlet规范中定义的,也就是说过滤器Filter的使用依赖于Tomcat等容器,导致它只能在web程序中使用。

     拦截器是一个Sping组件,由Spring管理,不依赖于Tomcat容器,是可以单独使用的。也可以应用于Application、Swing容器中。

    2.3 执行顺序不同

    在有的项目中,既有过滤器又有拦截器,那么它们两者之间的执行顺序是谁先谁后呢?先过滤器->再拦截器

     在上面说过,Filter是依赖于Tomcat容器的,所以请求是在进入Tomcat之后、进入Servet之前对请求进行一个预处理,然后进入Servlet,再经过拦截器进行处理、最后进入我们的Controller。

    为了证实上述所说:我们可以在一个项目中同时配置过滤器和拦截器(其余配置不在展示,可以参考上述两篇文章),

    过滤器:

    1. @WebFilter("/*")
    2. public class MyFilterOne implements Filter {
    3. /**
    4. * web应用启动时,web服务器将创建Filter的实例对象,并调用init方法,读取web.xml的配置,完成对象的初始化功能,
    5. * 从而为后续的用户请求做好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次,开发人员通过init的参数,
    6. * 可或得代表当前filter配置信息的FilterConfig对象)
    7. * @param filterConfig
    8. * @throws ServletException
    9. */
    10. @Override
    11. public void init(FilterConfig filterConfig) throws ServletException {
    12. }
    13. /**
    14. * 这个方法完成实际的过滤操作,当客户请求访问与过滤器相关联的URL的时候,Servlet过滤器将先执行doFilter方法,FilterChain参数用于访问后续过滤器
    15. * @param servletRequest
    16. * @param servletResponse
    17. * @param filterChain
    18. * @throws IOException
    19. * @throws ServletException
    20. */
    21. @Override
    22. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    23. System.out.println("我是过滤器,我进来了");
    24. filterChain.doFilter(servletRequest, servletResponse);
    25. }
    26. /**
    27. * filter创建后会保存在内存中,当web应用移除或者服务器停止时才销毁,该方法在Filter的生命周期中仅执行一次,在这个方法中,可以释放过滤器使用的资源
    28. */
    29. @Override
    30. public void destroy() {
    31. }
    32. }

    拦截器:

    1. @Component
    2. public class HeaderInterceptor implements HandlerInterceptor {
    3. @Override
    4. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    5. System.out.println("进入拦截器=======执行前========");
    6. return true;
    7. }
    8. @Override
    9. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    10. System.out.println("进入拦截器=======执行中========");
    11. }
    12. @Override
    13. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    14. System.out.println("进入拦截器=======执行后========");
    15. }
    16. }

    Controller层:

    1. @RestController
    2. public class LoginController {
    3. @GetMapping("/test/filterAndInterceptor")
    4. public String testFilter(){
    5. System.out.println("我是controller");
    6. return "请看控制台谁先输出";
    7. }
    8. }

    访问: 

    控制台输出:

     可见:上述结论是正确的,请求先经过过滤器再经过拦截器。

    4 注入Bean的情况不同

    在有的业务场景中,会在过滤器或者拦器引入sevice,看看情况分别是怎么样

    1. @GetMapping("/test/filterAndInterceptor")
    2. public String testFilter(){
    3. System.out.println("我是controller");
    4. return "请看控制台谁先输出";
    5. }
    1. @Service
    2. public class LoginServiceImpl implements LoginService{
    3. @Override
    4. public void login() {
    5. System.out.println("我是service中登录方法");
    6. }
    7. }

    在过滤器中引入service:

    1. package com.liubujun.springbootinterceptor.filter;
    2. import com.liubujun.springbootinterceptor.service.LoginService;
    3. import javax.annotation.Resource;
    4. import javax.servlet.*;
    5. import javax.servlet.annotation.WebFilter;
    6. import java.io.IOException;
    7. /**
    8. * @Author: liubujun
    9. * @Date: 2022/10/16 19:26
    10. */
    11. @WebFilter("/*")
    12. public class MyFilterOne implements Filter {
    13. @Resource
    14. private LoginService loginService;
    15. /**
    16. * web应用启动时,web服务器将创建Filter的实例对象,并调用init方法,读取web.xml的配置,完成对象的初始化功能,
    17. * 从而为后续的用户请求做好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次,开发人员通过init的参数,
    18. * 可或得代表当前filter配置信息的FilterConfig对象)
    19. * @param filterConfig
    20. * @throws ServletException
    21. */
    22. @Override
    23. public void init(FilterConfig filterConfig) throws ServletException {
    24. }
    25. /**
    26. * 这个方法完成实际的过滤操作,当客户请求访问与过滤器相关联的URL的时候,Servlet过滤器将先执行doFilter方法,FilterChain参数用于访问后续过滤器
    27. * @param servletRequest
    28. * @param servletResponse
    29. * @param filterChain
    30. * @throws IOException
    31. * @throws ServletException
    32. */
    33. @Override
    34. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    35. System.out.println("我是过滤器,我进来了");
    36. loginService.login();
    37. filterChain.doFilter(servletRequest, servletResponse);
    38. }
    39. /**
    40. * filter创建后会保存在内存中,当web应用移除或者服务器停止时才销毁,该方法在Filter的生命周期中仅执行一次,在这个方法中,可以释放过滤器使用的资源
    41. */
    42. @Override
    43. public void destroy() {
    44. }
    45. }

    访问之后控制台输出:一切正常

     在拦截器中引入service :

    1. @Component
    2. public class HeaderInterceptor implements HandlerInterceptor {
    3. @Resource
    4. private LoginService loginService;
    5. @Override
    6. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    7. System.out.println("进入拦截器=======执行前========");
    8. return true;
    9. }
    10. @Override
    11. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    12. loginService.login();
    13. System.out.println("进入拦截器=======执行中========");
    14. }
    15. @Override
    16. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    17. System.out.println("进入拦截器=======执行后========");
    18. }
    19. }

    以上只是部分内容,为了维护方便,本文已迁移到新地址:过滤器和拦截器的区别 – 编程屋

  • 相关阅读:
    2023年11月15号期中测验判断题(Java)
    RabbitMQ(六) 延迟消息队列
    2.8 Nginx负载均衡之ip_hash
    div内文字水平居中+垂直居中
    算法学习——贪心算法
    毕设-原创医疗预约挂号平台分享
    全网最详细的Gephi安装与使用教程
    基于SSM的高校运动会管理网站-计算机毕业设计源码
    1.常用文件管理命令
    贷中客群评级的场景实现,来试试这些多维的实操方法
  • 原文地址:https://blog.csdn.net/qq_50652600/article/details/127414711