Spring中的拦截器与过滤器:原理、区别与案例解析

前言

在Web应用中,我们经常需要对用户的请求进行某种处理,比如权限验证、日志记录等。

Spring框架提供了两种机制来实现这一需求:拦截器和过滤器。虽然它们的目标相似,但在使用上存在一些差异。本篇文章我们将详细探讨这两种机制的原理、区别,希望能给各位大佬带来帮助!

拦截器(Interceptor)

  1. 原理

拦截器是Spring MVC框架的一部分,它允许你在请求被实际处理之前或之后执行某些操作。拦截器基于Java的反射机制,可以拦截到方法级别的请求。

  1. 实现

实现一个拦截器需要实现HandlerInterceptor接口,并重写preHandle、postHandle和afterCompletion方法。

其中,preHandle方法在请求被处理之前调用,可以用于权限验证等;postHandle方法在请求被处理之后,但在视图渲染之前调用;afterCompletion方法在整个请求处理完成后调用。

  1. 配置

在Spring MVC的配置文件中,可以通过<mvc:interceptors>标签来配置拦截器,并指定其拦截的路径。

  1. 举个栗子

比如我们使用拦截器来实现权限验证。

java 复制代码
@Component  
public class AuthInterceptor implements HandlerInterceptor {  
    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  
        // 简单的权限验证逻辑  
        String role = request.getSession().getAttribute("role");  
        if ("admin".equals(role)) {  
            return true;  // 允许请求继续  
        } else {  
            response.sendRedirect("/access-denied");  // 重定向到拒绝访问页面  
            return false;  // 中断请求  
        }  
    }  
}

三、过滤器(Filter)

  1. 原理

过滤器是Servlet规范的一部分,它允许你在请求到达Servlet之前或响应离开Servlet之后执行某些操作。过滤器基于函数回调,可以拦截到请求和响应对象,但对具体的处理方法不可见。

  1. 实现

实现一个过滤器需要实现Filter接口,并重写doFilter方法。在该方法中,你可以对请求和响应对象进行操作。

  1. 配置

在web.xml文件中,可以通过<filter>和<filter-mapping>标签来配置过滤器,并指定其过滤的路径。

  1. 举个栗子

比如我们使用过滤器设置字符编码。

java 复制代码
@WebFilter(urlPatterns = "/*")  
public class EncodingFilter implements Filter {  
    @Override  
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
        request.setCharacterEncoding("UTF-8");  // 设置请求字符编码  
        response.setCharacterEncoding("UTF-8");  // 设置响应字符编码  
        chain.doFilter(request, response);  // 继续处理请求  
    }  
}

四、拦截器与过滤器的区别

这块是面试中的重点,在秋招中好几次被问到了这一点,在这里详细总结下:

  1. 规范不同:拦截器是Spring MVC框架的一部分,而过滤器是Servlet规范的一部分。
  2. 拦截级别不同:拦截器可以拦截到方法级别的请求,而过滤器只能拦截到请求和响应对象。
  3. 使用范围不同:拦截器只能用于Spring MVC项目,而过滤器可以用于任何基于Servlet的项目。
  4. 执行顺序不同:过滤器的执行顺序由其在web.xml中的配置顺序决定,而拦截器的执行顺序由其在Spring MVC配置文件中的配置顺序决定。

再举个栗子,现在我们要做一个用户登录操作,我们来看两者都是怎么实现的:

  1. 使用拦截器实现 :在preHandle方法中,检查用户的登录状态。如果用户已登录,则返回true让请求继续处理;如果用户未登录,则重定向到登录页面。
  2. 使用过滤器实现 :在doFilter方法中,同样检查用户的登录状态。如果用户已登录,则调用chain.doFilter(request, response)让请求继续处理;如果用户未登录,则重定向到登录页面。

文章到这里就先结束了,后续会继续分享相关的知识点。

相关推荐
IT_陈寒9 分钟前
当Java的hashCode遇上Lombok,我的缓存被全清了
前端·人工智能·后端
XW29 分钟前
常用提示词(Prompt)框架总结
后端
ServBay37 分钟前
DeepSeek 再次崩了,DeepSeek V5正在路上?
后端·deepseek
IT规划师1 小时前
编程术语中的同步与异步:从"等不等"到工程取舍
后端·面试
孟陬2 小时前
Foobar 技术周刊#159:当看不懂代码时,如何高效排障调试。脏页陷阱:一条只读查询,写入数 TB 数据。推测解码:大模型加速利器
前端·人工智能·后端
GoGeekBaird2 小时前
别再给每个 AI 做自我介绍了:我做了一个「个人上下文」管理系统
后端·github·agent
码事漫谈3 小时前
腾讯混元 Hy4 正式版发布了
后端
Mikko73 小时前
Redis 连接数满了服务端有错误信息吗?连接数不增加却命令超时?6.2 实测连接池、超时与大 key 怎么判定
java·spring boot·redis·后端
苍何4 小时前
DeepSeek的Super-agent 设计,和我们的工程实践
后端
Patrick_Wilson4 小时前
第一次读 Go 项目:从两个源码文件弄清 package、import 和 go.mod
后端·go·编程语言