HandlerInterceptor、okhttp3.Interceptor、feign.RequestInterceptor 三个拦截器对比
·
之前介绍了常见的三个拦截器HandlerInterceptor、okhttp3.Interceptor、feign.RequestInterceptor 的用法:
这3个拦截器都是基于 责任链模式(Chain of Responsibility),支持多个拦截器顺序执行;核心目标一致,为了解决 横切关注点(Cross-Cutting Concerns),但所属层级和拦截阶段不一样, 这里对比下三者的区别和使用场景。
1. 核心功能对比
| 维度 | HandlerInterceptor (Spring MVC) | okhttp3.Interceptor (OkHttp) | feign.RequestInterceptor (OpenFeign) |
|---|---|---|---|
| 层级位置 | 服务端 Web 层 | 客户端网络传输层 | 客户端接口抽象层 |
| 所属框架 | Spring Web MVC / Spring Boot | OkHttp 网络库 | OpenFeign (声明式HTTP客户端) |
| 框架定位 | 服务端 Web 框架 | 客户端网络库 | 声明式 HTTP 客户端框架 |
| 作用对象 | HTTP 请求/响应的 服务端处理阶段 | HTTP 请求/响应的 网络传输阶段 | 在Feign客户端构造请求的阶段 |
| 拦截阶段 | Controller 方法的执行前后 | 网络请求的发送和响应接收的原始字节流阶段 | 在Feign将方法调用转换为HTTP请求的过程中 |
| 操作对象 | HttpServletRequest/Response | OkHttp的 Request/Response (原始字节流或封装对象) | Feign的RequestTemplate (请求模板对象) |
| 主要用途 | 权限校验、日志、全局业务处理 | 修改请求头、添加认证、重试机制、日志记录 | 统一添加请求头、认证信息 |
| 能否修改请求体 | ✅ (需包装请求对象HttpServletRequest) | ✅ (直接操作 Request 和 Response) | ✅ (通过模板RequestTemplate修改) |
| 能否修改响应体 | ✅ (需包装响应对象) | ✅ (直接操作) | ❌ (不处理响应) |
| 请求中断能力 | ✅ (返回 false 或直接响应) | ✅ (抛出异常或返回自定义 Response) | ❌ (仅修改请求) |
| 典型依赖关系 | 内置于 Spring MVC | 独立网络库 | 依赖 OpenFeign |
2. 区别分析
1. 设计定位差异

-
HandlerInterceptor 服务于 Spring MVC 服务端框架,拦截目标是
Controller方法的执行,属于 Web 请求处理链的一部分:preHandle():Controller 执行前(权限校验)postHandle():Controller 执行后(日志记录)afterCompletion():视图渲染后(资源清理)
-
okhttp3.Interceptor 作用于 OkHttp 客户端网络库,拦截的是 HTTP 网络请求/响应的原始字节流,用于在发送请求前或接收响应后修改数据:
- 操作原始字节流(如 Gzip 压缩)
- 可修改请求/响应头、体
- 支持网络级重试、熔断
-
feign.RequestInterceptor 作用于 Feign 声明式HTTP客户端,在Feign将接口方法转化为HTTP请求的过程中,允许修改请求模板(
RequestTemplate)。它工作在请求被发送到网络之前,属于更高层次的请求构造拦截:- 在 Java 接口方法转 HTTP 请求时介入
- 只能修改请求模板(如统一添加
Authorization头) - 不接触实际网络传输
2. 技术能力对比
| 能力 | HandlerInterceptor | okhttp3.Interceptor | feign.RequestInterceptor |
|---|---|---|---|
| 修改 URL 参数 | ✅ | ✅ | ✅ |
| 修改请求头 | ✅ | ✅ | ✅ |
| 修改请求体内容 | ⚠️ (需复杂包装) | ✅ | ✅ |
| 拦截响应并修改数据 | ✅ | ✅ | ❌ |
| 实现自动重试机制 | ❌ | ✅ | ❌ |
| 直接操作网络套接字 | ❌ | ✅ | ❌ |
| 与业务逻辑深度集成 | ✅ | ❌ | ⚠️ (浅层集成) |
3. 代码结构差异
// Spring 的 HandlerInterceptor
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
//在服务端记录请求日志 & 鉴权
log.info("Request URL: {}", request.getRequestURL());
if (!isValid(request.getHeader("Token"))) {
response.setStatus(401);
return false; // 中断请求
}
return true;
}
}
// OkHttp 的 Interceptor
public class LoggingInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
// 在OkHttp中添加统一User-Agent
Request request = chain.request();
Request newRequest = originalRequest.newBuilder()
.header("User-Agent", "MyApp/1.0")
.build();
return chain.proceed(request); // 执行网络请求
}
}
// Feign 的 RequestInterceptor
public class FeignAuthInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
template.header("API-Key", "xxxxxx"); // 在Feign客户端请求中添加认证头
}
}
3.三者协作演示
场景描述:
-
当通过 Feign 客户端 调用
@FeignClient接口时:feign.RequestInterceptor先添加统一的API-Key请求头
-
OkHttp 底层发送请求时:
okhttp3.Interceptor添加User-Agent并记录原始日志- 实现失败自动重试(如 503 状态码重试 3 次)
-
请求到达 Spring Boot 服务端:
HandlerInterceptor校验请求头中的 Token 有效性- 校验失败直接返回 401 响应,不会进入 Controller
对应微服务架构中的工作流:

4. 如何选择
| 需求场景 | 推荐拦截器 | 原因 |
|---|---|---|
| 在 Spring MVC 中实现权限控制 | HandlerInterceptor | 深度集成服务端生命周期 |
| 需要修改网络层细节(如重试/压缩) | okhttp3.Interceptor | 直接操作网络流量 |
| 为所有 Feign 请求添加统一参数 | feign.RequestInterceptor | 声明式修改接口级请求模板 |
| 需要同时修改请求和响应原始字节 | okhttp3.Interceptor | 唯一支持双向字节流操作 |
| 在请求进入 Controller 前记录业务日志 | HandlerInterceptor | 可获取到 Spring 上下文业务数据 |
5.相关阅读
更多推荐
所有评论(0)