首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >拦截器 Interceptor 详解

拦截器 Interceptor 详解

作者头像
艾伦耶格尔
发布2025-08-28 14:36:31
发布2025-08-28 14:36:31
13400
代码可运行
举报
文章被收录于专栏:Java基础Java基础
运行总次数:0
代码可运行

想象一下,你正在指挥一场复杂的交响乐演出。作为指挥家,你需要在乐曲演奏过程中,精准地控制每个声部的演奏时机和节奏变化。在软件开发领域,Interceptor 就像一位经验丰富的指挥家,它能够在不改变程序原有结构的情况下,灵活地拦截程序的执行流程,并在关键节点插入额外的处理逻辑,就像指挥家在乐谱上添加一些精妙的装饰音,让程序的演奏更加优雅动听。

一、Interceptor 概念
1.1 什么是 Interceptor?

在 Web 应用中,用户的请求就像一张张乐谱,而 Controller 方法则是演奏乐曲的各个声部。Interceptor 就像一位掌控全局的指挥家,它能够拦截住用户的每一个请求,并在请求到达目标 Controller 方法之前或之后,执行一些预先安排好的动作,例如检查用户是否登录、记录请求日志、修改请求参数等等。

1.2 Interceptor 的作用
  • 预处理请求 (preHandle): 就像指挥家在乐曲演奏之前,需要先确定每个声部的演奏顺序和节奏一样,Interceptor 可以在请求到达目标 Controller 方法之前,执行一些预处理逻辑,例如:
    • 检查用户是否登录: 就像核对演奏者身份一样,确保只有授权用户才能访问特定资源。
    • 校验请求参数: 就像检查乐器的音准一样,确保输入数据的合法性和安全性,避免出现“走调”的情况。
    • 记录请求日志: 就像记录演奏时间和曲目一样,方便日后追踪问题和分析用户行为。
  • 后处理响应 (postHandle): 如同指挥家在乐章结束后,需要对演奏效果进行点评一样,Interceptor 可以在目标 Controller 方法执行完毕后,对响应进行一些后处理操作,例如:
    • 统一处理异常: 就像及时纠正演奏中的错误一样,避免将程序异常直接暴露给用户,提供更加友好的提示信息。
    • 对响应数据进行加密或压缩: 就像对录音进行后期处理一样,提高数据传输效率和安全性。
    • 记录响应时间: 就像统计乐曲演奏时间一样,监控系统性能,找出程序的“瓶颈”所在。
  • 最终处理 (afterCompletion): 如同指挥家在整场演出结束后,需要对舞台进行清理和整理一样,Interceptor 可以在视图渲染完毕后,执行一些最终的清理工作,例如:
    • 释放资源: 关闭数据库连接、释放文件句柄等,避免资源泄露。
    • 记录最终的响应状态码和响应时间: 方便监控系统运行状况。
1.3 Interceptor 与 Filter 的区别

虽然 Interceptor 和 Filter 都可以拦截请求,但它们就像指挥家和舞台监督一样,负责不同的工作:

  • 拦截目标不同: Filter 位于 Servlet 容器级别,就像舞台监督一样,负责管理所有演员(Servlet 和 JSP)的进出场顺序;而 Interceptor 位于 Spring MVC 框架内部,就像指挥家一样,只负责指挥演奏者(Controller)的演奏过程。
  • 工作机制不同: Filter 基于回调函数机制,就像舞台监督通过广播通知演员一样;而 Interceptor 基于 Java 反射机制,就像指挥家通过指挥棒直接控制演奏者一样。
  • 使用场景不同: Filter 通常用于处理与 Servlet API 相关的通用逻辑,例如设置字符编码、Gzip 压缩等,就像舞台监督负责舞台灯光和音响效果一样;而 Interceptor 更适合处理与业务逻辑相关的通用逻辑,例如权限验证、日志记录等,就像指挥家负责乐曲的艺术表现力一样,属于spring 框架提供的。
二、Spring MVC Interceptor
2.1 三大核心方法

Spring MVC Interceptor 提供了三个核心方法,就像指挥家的指挥棒一样,可以灵活地控制程序的执行流程:

  • preHandle(HttpServletRequest request, HttpServletResponse response, Object handler): 这是演奏开始前的准备工作,就像指挥家在乐章开始前,需要先确定演奏的节奏和速度一样,该方法在 Controller 方法执行之前被调用,可以用于预处理请求,例如:
    • 判断用户是否登录:如果未登录,则可以重定向到登录页面,并返回 false,阻止请求继续执行;如果已登录,则返回 true,允许请求继续执行。
    • 校验请求参数:如果参数不合法,则可以设置错误信息,并返回 false,阻止请求继续执行;如果参数合法,则返回 true,允许请求继续执行。
  • postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView): 这是乐章演奏后的点评环节,就像指挥家在乐章结束后,需要对演奏效果进行点评一样,该方法在 Controller 方法执行完毕后,但在视图渲染之前被调用,可以用于修改 ModelAndView 对象,例如:
    • 添加模型数据:例如,可以添加一些通用的页面元素,例如网站标题、用户信息等等。
    • 修改视图名称:例如,可以根据用户的角色,跳转到不同的页面。
  • afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex): 这是演出结束后的谢幕时间,就像指挥家在整场演出结束后,需要向观众谢幕一样,该方法在视图渲染完毕后被调用,可以用于资源清理、记录响应日志等。

简而言之:

        1.preHandle方法:目标资源方法执行前执行。 返回true:放行 返回false:不放行

        2.postHandle方法:目标资源方法执行后执行

        3.afterCompletion方法:视图渲染完毕后执行,最后执行

2.2 代码示例
代码语言:javascript
代码运行次数:0
运行
复制
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 预处理逻辑,例如打印请求路径
        System.out.println("Interceptor - preHandle: " + request.getRequestURI());

        // 执行权限检查逻辑...
        boolean hasPermission = checkPermission(request); 
        if (!hasPermission) {
            // 如果没有权限,设置响应状态码为403,并返回false阻止请求继续执行
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            return false;
        }

        // 返回 true,表示放行,继续执行下一个拦截器或目标 Controller 方法
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 后处理逻辑,例如添加模型数据
        System.out.println("Interceptor - postHandle");
        if (modelAndView != null) {
            modelAndView.addObject("message", "来自拦截器的问候!");
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 资源清理、记录响应日志等操作
        System.out.println("Interceptor - afterCompletion");
    }

    // 模拟权限检查方法
    private boolean checkPermission(HttpServletRequest request) {
        // ... 检查用户是否具有访问权限 ...
        return true;
    }
}
2.3 配置 Interceptor
  • 基于 Java 代码配置: 我们可以通过实现 WebMvcConfigurer 接口,并重写 addInterceptors() 方法来注册自定义的拦截器。
代码语言:javascript
代码运行次数:0
运行
复制
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**") // 设置拦截路径,例如拦截所有请求
                .excludePathPatterns("/login", "/register"); // 设置排除路径,例如排除登录和注册请求
    }
}
  • 基于 XML 文件配置: 我们也可以在 Spring MVC 的配置文件中使用 <mvc:interceptors> 元素来注册自定义的拦截器。
代码语言:javascript
代码运行次数:0
运行
复制
<mvc:interceptors>
    <bean class="com.example.MyInterceptor">
        <property name="mappedPatterns">
            <list>
                <value>/**</value> <!-- 设置拦截路径 -->
            </list>
        </property>
        <property name="excludedPatterns">
            <list>
                <value>/login</value> <!-- 设置排除路径 -->
                <value>/register</value>
            </list>
        </property>
    </bean>
</mvc:interceptors>
三、实战演练:Interceptor 实现登录校验
3.1 需求分析

假设我们正在开发一个电商网站,用户需要登录才能进行下单操作。为了保证网站安全,我们需要使用 Interceptor 对所有下单请求进行拦截,检查用户是否登录,如果未登录,则跳转到登录页面。

3.2 代码实现
代码语言:javascript
代码运行次数:0
运行
复制
@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取用户信息
        User user = (User) request.getSession().getAttribute("user");

        // 判断用户是否登录
        if (user == null) {
            // 未登录,跳转到登录页面
            response.sendRedirect("/login");
            return false; // 拦截请求
        }

        // 已登录,放行请求
        return true;
    }
}
3.3 配置 Interceptor
代码语言:javascript
代码运行次数:0
运行
复制
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/order/**"); // 拦截所有以 /order/ 开头的请求
    }
}
四、总结:

Interceptor 是构建灵活、可扩展 Web 应用的利器,它能够帮助我们优雅地处理横切关注点,提高代码复用性,降低系统耦合度。掌握 Interceptor 的使用,能够让我们开发出更加健壮、易于维护的 Web 应用,就像一位经验丰富的指挥家,能够指挥乐团演奏出美妙动听的乐章。

以上就是关于拦截器Interceptor的详解,希望对各位有所帮助,感谢各位看官的观看,谢谢~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Interceptor 概念
    • 1.1 什么是 Interceptor?
    • 1.2 Interceptor 的作用
    • 1.3 Interceptor 与 Filter 的区别
  • 二、Spring MVC Interceptor
    • 2.1 三大核心方法
    • 2.2 代码示例
    • 2.3 配置 Interceptor
  • 三、实战演练:Interceptor 实现登录校验
    • 3.1 需求分析
    • 3.2 代码实现
    • 3.3 配置 Interceptor
  • 四、总结:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档