您的位置:首页 > 新闻 > 热点要闻 > 免费商标图案设计logo_秦皇岛市住房公积金管理中心_疫情排行榜最新消息_seo发外链的网站

免费商标图案设计logo_秦皇岛市住房公积金管理中心_疫情排行榜最新消息_seo发外链的网站

2025/4/18 3:22:20 来源:https://blog.csdn.net/zp357252539/article/details/146588021  浏览:    关键词:免费商标图案设计logo_秦皇岛市住房公积金管理中心_疫情排行榜最新消息_seo发外链的网站
免费商标图案设计logo_秦皇岛市住房公积金管理中心_疫情排行榜最新消息_seo发外链的网站

Spring 拦截器链(Interceptor Chain)完整示例


核心目标

展示 多个 Interceptor 组成拦截器链的完整实现,包含 preHandle()postHandle()afterCompletion() 全生命周期方法,以及如何通过 WebMvcConfigurer 控制执行顺序。最后用表格总结拦截器生命周期。


代码结构
  1. 拦截器 1:记录请求时间(TimingInterceptor)。
  2. 拦截器 2:权限验证(AuthInterceptor)。
  3. 拦截器链配置:通过 WebMvcConfigurer 控制顺序。
  4. 测试 Controller:验证拦截器链执行流程。

完整代码示例


1. 拦截器 1:记录请求时间
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class TimingInterceptor implements HandlerInterceptor {private long startTime; // 记录请求开始时间// **前置处理(preHandle)**@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {startTime = System.currentTimeMillis();System.out.println("TimingInterceptor 前置处理开始");return true; // 返回 true 继续处理,false 中断请求}// **后置处理(postHandle)**@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {long endTime = System.currentTimeMillis();System.out.println("TimingInterceptor 后置处理,总耗时:" + (endTime - startTime) + "ms");}// **完成处理(afterCompletion)**@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {System.out.println("TimingInterceptor 完成处理(请求结束)");}
}

2. 拦截器 2:权限验证
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class AuthInterceptor implements HandlerInterceptor {// **前置处理(preHandle)**@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String token = request.getHeader("Authorization");if (token == null || !token.equals("valid_token")) {System.out.println("权限验证失败,拒绝访问");response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);return false; // 中断请求}System.out.println("权限验证通过");return true;}// **后置处理(postHandle)**@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {System.out.println("AuthInterceptor 后置处理(Controller 执行后)");}// **完成处理(afterCompletion)**@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {System.out.println("AuthInterceptor 完成处理(请求完全结束)");}
}

3. 拦截器链配置类
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册 TimingInterceptor(顺序1)registry.addInterceptor(new TimingInterceptor()).order(1) // 优先级最高(数值越小优先级越高).addPathPatterns("/**"); // 拦截所有路径// 注册 AuthInterceptor(顺序2)registry.addInterceptor(new AuthInterceptor()).order(2) // 优先级次之.addPathPatterns("/**").excludePathPatterns("/login"); // 排除登录接口}
}

4. 测试 Controller
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TestController {@GetMapping("/test")public String test() {System.out.println("Controller 方法执行");return "Hello from Controller!";}@GetMapping("/login")public String login() {return "登录成功";}
}

5. 启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

执行流程与输出结果

访问 /test 接口(假设请求头包含 Authorization: valid_token),控制台输出如下:

TimingInterceptor 前置处理开始
权限验证通过
AuthInterceptor 后置处理(Controller 执行后)
TimingInterceptor 后置处理,总耗时:Xms
AuthInterceptor 完成处理(请求完全结束)
TimingInterceptor 完成处理(请求结束)
Controller 方法执行

拦截器生命周期总结表格

方法执行时机作用
preHandle()Controller 方法执行前调用。预处理请求(如权限校验、日志记录),返回 false 可中断请求流程。
postHandle()Controller 方法执行后,视图渲染前调用。后置处理(如修改响应数据、记录日志),不影响请求流程。
afterCompletion()请求完全处理后调用(包括视图渲染完成或发生异常)。最终清理操作(如释放资源、记录请求结束状态)。

关键点说明

  1. 拦截器链顺序控制

    • 通过 InterceptorRegistry.order() 设置优先级(数值越小优先级越高)。
    • preHandle() 方法按 order 顺序执行,postHandle()afterCompletion() 按逆序执行。
  2. 生命周期阶段对比

    • preHandle():决定是否继续请求流程。
    • postHandle():修改响应数据(如添加公共字段)。
    • afterCompletion():资源释放(如关闭数据库连接)。
  3. 典型应用场景

    • preHandle():权限校验、请求参数校验。
    • postHandle():统一返回格式封装、日志记录。
    • afterCompletion():性能监控、异常统计。

常见问题

  1. 如何动态调整拦截器顺序?

    • 修改 order() 的数值,无需重启应用即可生效。
  2. preHandle() 返回 false 后如何处理?

    • 请求立即终止,后续拦截器和 Controller 不会执行,需在 preHandle() 中设置响应状态码(如 401)。
  3. afterCompletion() 是否在异常时执行?

    • 是的,无论请求是否成功,afterCompletion() 都会执行,可通过 Exception ex 参数获取异常信息。

执行流程图

请求到达 →
├─ TimingInterceptor.preHandle() →
│  ├─ 返回 true → 继续链 →
│  ├─ AuthInterceptor.preHandle() →
│  │  ├─ 返回 true → 执行 Controller →
│  │  └─ AuthInterceptor.postHandle() →
│  └─ TimingInterceptor.postHandle() →
└─ 返回响应 →├─ AuthInterceptor.afterCompletion() →└─ TimingInterceptor.afterCompletion()

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com