当前位置: 首页 > article >正文

Spring Boot的过滤器与拦截器的区别

Spring Boot中的过滤器和拦截器是处理HTTP请求和响应的两种不同机制,它们在多个方面存在显著的区别。

一、定义与归属:
1.1 过滤器(Filter):
--- 过滤器是Java Servlet规范的一部分,可以在Servlet上下文中使用。
--- 它工作在Servlet容器级别,用于在请求和响应之间插入自定义逻辑。
1.2 拦截器(Interceptor):
--- 拦截器是Spring框架的一部分,主要用于拦截和处理HTTP请求。
--- 它是基于AOP(面向切面编程)实现的,通过实现HandlerInterceptor接口来定义。
二、实现方式:
2.1 过滤器:
--- 过滤器需要实现javax.servlet.Filter接口。
--- 主要方法包括init(FilterConfig filterConfig)(用于初始化过滤器)、doFilter(ServletRequest request, ServletResponse response, FilterChain chain)(执行过滤逻辑)和destroy()(用于销毁过滤器)。
2.2 拦截器:
--- 拦截器需要实现HandlerInterceptor接口。
--- 主要方法包括preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)(在请求处理之前执行)、postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)(在请求处理之后、视图渲染之前执行)和afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)(在整个请求处理完成后执行)。
三、触发时机与执行顺序:
3.1 过滤器:
--- 过滤器在请求到达Servlet或JSP之前被调用,并在响应返回给客户端之前执行。
--- 其执行顺序由在web.xml配置文件中的顺序或Spring配置中的注册顺序决定。
3.2 拦截器:
--- 拦截器在请求处理的不同阶段进行拦截,如preHandle、postHandle、afterCompletion。
--- 其执行顺序由在Spring配置文件中的注册顺序决定。
--- 当有多个拦截器时,它们的preHandle方法按注册顺序执行,而postHandle和afterCompletion方法按注册顺序的逆序执行。
四、处理范围与功能:
4.1 过滤器:
--- 过滤器可以处理所有类型的请求,包括静态资源请求,而不仅仅是Spring MVC请求。
--- 常用于日志记录、安全检查、字符编码转换、请求响应压缩等。
4.2 拦截器:
--- 拦截器主要针对Spring MVC请求进行拦截和处理。
--- 常用于权限验证、日志记录、性能监控、数据校验和缓存处理等。
五、访问Spring MVC上下文
5.1 过滤器不能直接访问Spring MVC的上下文信息。
5.2 拦截器可以访问Spring MVC的上下文信息,如HandlerMethod。
六、核心代码:
6.1 自定义过滤器类:

public class MyFilter implements Filter {  
    @Override  
    public void init(FilterConfig filterConfig) throws ServletException {  
        // 过滤器初始化逻辑  
        System.out.println("MyFilter init...");  
    } 
    @Override  
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)  
            throws IOException, ServletException {  
        // 过滤逻辑,可以对请求和响应进行处理  
        HttpServletRequest request = (HttpServletRequest) servletRequest;  
        System.out.println("MyFilter: " + request.getRequestURI());  
          
        // 将请求传递给下一个过滤器或目标资源  
        filterChain.doFilter(servletRequest, servletResponse);  
    }  
    @Override  
    public void destroy() {  
        // 过滤器销毁逻辑  
    }  
}

6.2 注册过滤器:可以通过FilterRegistrationBean来注册自定义过滤器。

@Configuration  
public class FilterConfig {  
    @Bean  
    public FilterRegistrationBean<MyFilter> registrationBean() {  
        FilterRegistrationBean<MyFilter> myFilter = new FilterRegistrationBean<>();  
        myFilter.setFilter(new MyFilter());  
        myFilter.addUrlPatterns("/*"); // 匹配所有URL  
        // 可以设置过滤器的执行顺序,数值越小优先级越高  
        myFilter.setOrder(1);  
        return myFilter;  
    }  
}

6.3 自定义拦截器类:

@Component  
public class MyInterceptor implements HandlerInterceptor {  
  
    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
        // 在请求处理之前执行,可以中断请求  
        System.out.println("/preHandler");  
        return true; // 返回true表示继续处理请求,返回false表示中断请求  
    }  
  
    @Override  
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)  
            throws Exception {  
        // 在请求处理之后、视图渲染之前执行  
        System.out.println("postHandler");  
    }  
  
    @Override  
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)  
            throws Exception {  
        // 在整个请求处理完成后执行,无论请求是否成功都会执行  
        System.out.println("afterCompletion");  
    }  
}

6.4 注册拦截器:可以通过实现WebMvcConfigurer接口来注册自定义拦截器。

@Configuration  
public class InterceptorConfig implements WebMvcConfigurer {  
  
    @Autowired  
    private MyInterceptor myInterceptor;  
  
    @Override  
    public void addInterceptors(InterceptorRegistry registry) {  
        registry.addInterceptor(myInterceptor)  
                .addPathPatterns("/**") // 匹配所有路径  
                .excludePathPatterns("/login", "/register"); // 排除某些路径  
    }  
}


http://www.kler.cn/a/387008.html

相关文章:

  • 开源项目推荐——OpenDroneMap无人机影像数据处理
  • Java 多线程(三)—— 死锁
  • 穿越数据迷宫:C++哈希表的奇幻旅程
  • Vue.js 项目创建流程
  • 信号-3-信号处理
  • 学习记录:js算法(九十二):克隆图
  • 【C++ 滑动窗口】2134. 最少交换次数来组合所有的 1 II
  • Anaconda安装和环境配置教程(2024年11月9日)
  • Kafka 之事务消息
  • GJ Round (2024.10) Round 8~21
  • 鸿蒙多线程开发——Worker多线程
  • 安全见闻(网络安全篇)
  • Python爬虫如何处理验证码与登录
  • Python练习15
  • Qt 无法获取调试输出
  • SpringBoot助力的共享汽车业务优化系统
  • 【c++丨STL】vector模拟实现
  • JAVA 多线程之ForkJoin
  • 发现了NitroShare的一个bug
  • 关于vue如何监听route和state以及各自对应的实际场景
  • 103 - Lecture 1
  • Web前端开发--HTML语言
  • Conpair: 配对样本一致性concordance与污染contamination分析
  • LLMs之MemFree:MemFree的简介、安装和使用方法、案例应用之详细攻略
  • 论文精读:NC kagome FeGe 自旋声子耦合驱动CDW 实验与理论计算
  • CCF ChinaOSC |「开源科学计算与系统建模openSCS专题分论坛」11月9日与您相约深圳