
在 Spring Boot3 的开发过程中,相信不少开发者都在拦截器和过滤器的使用上花费了大量时间和精力。复杂的配置流程、模糊不清的原理概念,让大家在实际运用时常常感到困惑。今天,咱们就来全方位梳理一下 Spring Boot3 中拦截器和过滤器的详细使用方式,帮你拨开迷雾,轻松驾驭它们。
背景介绍随着互联网应用的不断发展,对项目的安全性、性能优化以及功能拓展等方面提出了更高要求。Spring Boot3 作为当下极为流行的开发框架,其拦截器和过滤器发挥着不可或缺的作用。过滤器,源于 J2EE 中的 Servlet 技术,它基于 Servlet 的函数回调来实现功能。在项目中,它主要负责对请求进行预处理和后处理,比如权限认证、敏感词检测、访问日志记录等场景都能看到它的身影。而拦截器则是 Spring 框架中的重要组件,它不依赖于 Servlet 容器,却依赖于 Spring。通过反射机制和动态代理实现功能,拦截器不仅可以获取到 Spring 中存在的 Bean,还能对 action 请求进行处理,在访问日志记录、权限管理等方面应用广泛。可以说,熟练掌握拦截器和过滤器的使用,是提升 Spring Boot3 项目开发质量的关键。
解决方案介绍过滤器的使用实现 Filter 接口
开发者需要创建一个类,让它实现 Filter 接口。以一个简单的日志记录过滤器为例,代码如下:
import javax.servlet.*;import javax.servlet.annotation.WebFilter;import java.io.IOException;import org.slf4j.Logger;import org.slf4j.LoggerFactory;@WebFilter(filterName = "logFilter", urlPatterns = "/*")public LogFilter implements Filter { private static final Logger logger = LoggerFactory.getLogger(LogFilter.class); @Override public void init(FilterConfig filterConfig) throws ServletException { Filter.super.init(filterConfig); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { logger.info("请求开始处理,请求地址为:{}", servletRequest.getServletPath()); filterChain.doFilter(servletRequest, servletResponse); logger.info("请求处理结束"); } @Override public void destroy() { Filter.super.destroy(); }}在上述代码中,我们创建了LogFilter类实现Filter接口。doFilter方法中,在请求处理前记录请求开始日志,处理后记录请求结束日志。
放行请求
在doFilter方法中,处理完相关逻辑后,通过调用chain.doFilter()方法让请求继续传递。如上面代码中,filterChain.doFilter(servletRequest, servletResponse);这行代码确保了请求能顺利通过过滤器链到达后续处理环节。
启用过滤器
使用注解@WebFilter(),在注解中配置过滤器的名称、拦截路径等参数。如上述代码中@WebFilter(filterName = "logFilter", urlPatterns = "/*"),这里filterName指定过滤器名称为logFilter,urlPatterns = "/*"表示拦截所有请求路径。同时,要在 Spring Boot 的启动类上添加@ServletComponentScan注解,例如:
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.web.servlet.ServletComponentScan;@SpringBootApplication@ServletComponentScanpublic YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); }}通过这样的配置,Spring 才能扫描到自定义的过滤器并使其正常工作。
拦截器的使用实现 HandlerInterceptor 接口
创建一个类实现HandlerInterceptor接口。以一个简单的权限校验拦截器为例,代码如下:
import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public AuthInterceptor implements HandlerInterceptor { private static final Logger logger = LoggerFactory.getLogger(AuthInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 假设这里从请求头中获取token进行权限校验 String token = request.getHeader("token"); if (token == null ||!isValidToken(token)) { logger.warn("权限校验失败,无有效token"); response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "权限不足"); return false; } logger.info("权限校验通过"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // 这里可以对视图渲染前的ModelAndView进行一些处理 } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 这里可以进行资源清理等操作 } private boolean isValidToken(String token) { // 实际项目中这里应该是与认证服务器交互校验token的逻辑,这里简单返回true模拟通过 return true; }}在上述代码中,preHandle方法在请求处理前被调用,进行权限校验,如果校验不通过则返回错误信息,阻止请求继续处理。
注册拦截器
新建一个类,继承WebMvcConfigurer接口,实现addInterceptors方法。代码如下:
import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configurationpublic InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()) .addPathPatterns("/api/**") .excludePathPatterns("/api/login", "/api/register"); }}在上述代码中,通过registry.addInterceptor(new AuthInterceptor())注册了AuthInterceptor拦截器,.addPathPatterns("/api/**")表示拦截所有/api路径下的请求,.excludePathPatterns("/api/login", "/api/register")表示排除/api/login和/api/register路径,这些路径不进行拦截。
两者的区别与选择功能区别
过滤器只能获取到请求中的request和response,无法获取到响应方法的信息,而拦截器可以获取到 action 请求的上下文,能对请求的处理过程有更全面的把控。例如,在过滤器中无法直接获取到 Spring 容器中的 Bean,而拦截器可以。
应用场景选择
当需要对所有请求进行统一的预处理,如字符编码设置、日志记录等,过滤器更为合适。而在涉及到 Spring 框架的业务逻辑处理、权限控制等场景下,拦截器则能更好地发挥作用。例如,在一个电商项目中,对于所有请求的访问日志记录可以用过滤器实现,而对于用户购买商品时的权限校验则适合使用拦截器。
总结通过上面的详细讲解,相信大家对 Spring Boot3 中拦截器和过滤器的使用有了更清晰的认识。从它们的背景、具体使用方法到如何根据场景进行选择,每一步都为大家梳理到位。在实际开发中,希望大家能够多去实践,将这些知识运用到项目里。同时,也欢迎各位在评论区分享自己在使用拦截器和过滤器过程中的经验和遇到的问题,咱们一起交流探讨。