Hutool请求拦截:HTTP请求响应拦截
【免费下载链接】hutool 🍬A set of tools that keep Java sweet. 项目地址: https://gitcode.com/gh_mirrors/hu/hutool
还在为HTTP请求的全局处理而烦恼?每次都要手动添加相同的header、记录日志、处理异常?Hutool的HTTP拦截器机制让你一键解决这些痛点!本文将深入解析Hutool的HTTP请求响应拦截功能,带你掌握高效、灵活的HTTP请求处理方案。
什么是HTTP拦截器?
HTTP拦截器(Interceptor)是一种设计模式,允许你在HTTP请求发送前和响应接收后插入自定义处理逻辑。Hutool提供了强大的拦截器机制,支持:
- 请求拦截:在请求发送前修改请求参数、添加header、记录日志等
- 响应拦截:在响应接收后处理响应数据、记录日志、统一异常处理等
- 全局拦截:对所有HTTP请求生效的拦截器
- 局部拦截:对特定请求生效的拦截器
Hutool拦截器核心架构
Hutool的HTTP拦截器系统基于以下几个核心组件:
1. HttpInterceptor接口
@FunctionalInterface
public interface HttpInterceptor<T extends HttpBase<T>> {
void process(T httpObj);
}
这是一个函数式接口,支持Lambda表达式,非常简洁易用。
2. 拦截器链(Chain)模式
class Chain<T extends HttpBase<T>> implements cn.hutool.core.lang.Chain<HttpInterceptor<T>, Chain<T>> {
private final List<HttpInterceptor<T>> interceptors = new LinkedList<>();
// 链式添加、迭代器支持
}
采用责任链模式,支持多个拦截器按顺序执行。
3. 全局拦截器管理器
public enum GlobalInterceptor {
INSTANCE;
private final HttpInterceptor.Chain<HttpRequest> requestInterceptors = new HttpInterceptor.Chain<>();
private final HttpInterceptor.Chain<HttpResponse> responseInterceptors = new HttpInterceptor.Chain<>();
// 全局管理方法
}
单例模式确保全局拦截器的统一管理。
实战:四种拦截器使用场景
场景一:全局请求头自动添加
// 全局添加认证token
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
request.header("Authorization", "Bearer your-token-here");
});
// 后续所有请求都会自动携带token
HttpResponse response = HttpRequest.get("https://api.example.com/data").execute();
场景二:请求日志记录
// 记录请求信息
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
System.out.println("请求URL: " + request.getUrl());
System.out.println("请求方法: " + request.getMethod());
System.out.println("请求头: " + request.headers());
});
// 记录响应信息
GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
System.out.println("响应状态: " + response.getStatus());
System.out.println("响应内容长度: " + response.body().length);
});
场景三:统一异常处理
GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
if (response.getStatus() >= 400) {
// 统一处理错误响应
String errorMsg = "请求失败: " + response.getStatus() + " - " + response.body();
throw new RuntimeException(errorMsg);
}
});
try {
HttpResponse response = HttpRequest.get("https://api.example.com/error-endpoint").execute();
} catch (RuntimeException e) {
System.out.println("统一异常处理: " + e.getMessage());
}
场景四:请求参数预处理
// 对特定请求添加参数
HttpRequest request = HttpRequest.get("https://api.example.com/search")
.addRequestInterceptor(req -> {
req.form("timestamp", System.currentTimeMillis());
req.form("sign", generateSign(req));
})
.form("keyword", "hutool");
HttpResponse response = request.execute();
拦截器执行流程
高级特性详解
1. 拦截器优先级控制
由于拦截器按添加顺序执行,可以通过控制添加顺序来实现优先级:
// 先执行:基础认证
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
request.basicAuth("user", "pass");
});
// 后执行:业务特定处理
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
request.header("X-Request-ID", UUID.randomUUID().toString());
});
2. 条件性拦截
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
// 只对特定域名添加header
if (request.getUrl().contains("api.example.com")) {
request.header("X-API-Version", "v2");
}
});
GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
// 只处理JSON响应
if (response.header("Content-Type").contains("application/json")) {
JSONObject json = JSONUtil.parseObj(response.body());
// 处理JSON数据
}
});
3. 重定向时的拦截器控制
HttpRequest.get("https://example.com/redirect")
.setInterceptorOnRedirect(true) // 重定向时也使用拦截器
.setMaxRedirectCount(3)
.execute();
4. 性能监控拦截器
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
request.attr("startTime", System.currentTimeMillis());
});
GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
Long startTime = (Long) response.getRequest().attr("startTime");
long duration = System.currentTimeMillis() - startTime;
System.out.println("请求耗时: " + duration + "ms");
// 记录到监控系统
monitor.recordRequestDuration(duration, response.getStatus());
});
实战案例:完整的API客户端
public class ApiClient {
private static final String BASE_URL = "https://api.example.com";
static {
// 全局初始化
setupGlobalInterceptors();
}
private static void setupGlobalInterceptors() {
// 认证
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
request.basicAuth("api-user", "api-secret");
});
// 请求ID
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
request.header("X-Request-ID", UUID.randomUUID().toString());
});
// 性能监控
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
request.attr("startTime", System.currentTimeMillis());
});
GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
Long startTime = (Long) response.getRequest().attr("startTime");
long duration = System.currentTimeMillis() - startTime;
logRequest(response.getRequest(), response, duration);
});
// 错误处理
GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
if (response.getStatus() >= 400) {
handleErrorResponse(response);
}
});
}
public static JSONObject getUserInfo(String userId) {
return HttpRequest.get(BASE_URL + "/users/" + userId)
.addResponseInterceptor(response -> {
// 特定接口的响应处理
if (response.getStatus() == 404) {
return JSONUtil.createObj().put("error", "用户不存在");
}
})
.execute()
.bodyToJson();
}
public static JSONObject createUser(Map<String, Object> userData) {
return HttpRequest.post(BASE_URL + "/users")
.body(JSONUtil.toJsonStr(userData))
.addRequestInterceptor(request -> {
// 特定接口的请求处理
request.header("X-User-Operation", "create");
})
.execute()
.bodyToJson();
}
private static void logRequest(HttpRequest request, HttpResponse response, long duration) {
// 记录到日志系统
}
private static void handleErrorResponse(HttpResponse response) {
// 统一错误处理逻辑
}
}
拦截器最佳实践
1. 保持拦截器轻量
// 好:轻量级操作
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
request.header("X-Trace-ID", MDC.get("traceId"));
});
// 避免:重量级操作
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
// 避免在拦截器中执行数据库操作等重量级任务
// User user = userService.getCurrentUser(); // 不推荐
});
2. 异常处理策略
GlobalInterceptor.INSTANCE.addResponseInterceptor(response -> {
try {
// 拦截器逻辑
} catch (Exception e) {
// 妥善处理异常,避免影响其他拦截器
log.error("拦截器处理异常", e);
}
});
3. 线程安全考虑
// 使用线程安全的操作
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
// 使用线程安全的类
request.header("X-Thread-ID", Thread.currentThread().getName());
});
常见问题与解决方案
Q1: 拦截器执行顺序问题
问题:多个拦截器之间存在依赖关系,需要控制执行顺序。
解决方案:
// 明确控制添加顺序
GlobalInterceptor.INSTANCE.clear(); // 清空现有拦截器
// 按依赖顺序添加
GlobalInterceptor.INSTANCE.addRequestInterceptor(authInterceptor);
GlobalInterceptor.INSTANCE.addRequestInterceptor(loggingInterceptor);
GlobalInterceptor.INSTANCE.addRequestInterceptor(businessInterceptor);
Q2: 特定请求不需要某些全局拦截器
问题:全局拦截器对某些特殊请求不适用。
解决方案:
// 方法1:使用局部拦截器覆盖
HttpRequest.get("https://special.api.com/data")
.addRequestInterceptor(request -> {
// 特殊处理,不执行某些全局逻辑
})
.execute();
// 方法2:条件判断
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
if (!request.getUrl().contains("special.api.com")) {
// 正常执行全局逻辑
}
});
Q3: 拦截器性能影响
问题:拦截器过多影响请求性能。
解决方案:
// 使用条件执行
GlobalInterceptor.INSTANCE.addRequestInterceptor(request -> {
if (needLogging(request)) { // 条件判断
// 执行相对耗时的操作
logRequestDetails(request);
}
});
总结
Hutool的HTTP拦截器机制提供了强大而灵活的请求响应处理能力。通过本文的学习,你应该掌握:
- 核心概念:理解HttpInterceptor接口和拦截器链模式
- 四种使用场景:全局配置、日志记录、异常处理、参数预处理
- 高级特性:优先级控制、条件拦截、性能监控
- 最佳实践:保持轻量、妥善处理异常、线程安全
- 问题解决:常见问题的解决方案
拦截器模式极大地提升了HTTP请求处理的模块化和可维护性,让你能够以声明式的方式管理横切关注点(Cross-Cutting Concerns)。无论是简单的API调用还是复杂的企业级应用,Hutool的拦截器都能为你提供强大的支持。
现在就开始使用Hutool拦截器,让你的HTTP请求处理更加优雅和高效!
【免费下载链接】hutool 🍬A set of tools that keep Java sweet. 项目地址: https://gitcode.com/gh_mirrors/hu/hutool
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



