okhttp5.x 需要在 请求级别 控制是否使用重试拦截器,而不是在客户端级别
方案1:使用不同的 HttpClient(推荐)
创建两个不同的 HttpClient 实例:
public static final OkHttpClient httpClient; // 普通客户端(无重试)
public static final OkHttpClient httpClientWithRetry; // 带重试的客户端
static {
try {
executorService = createThreadPool();
// 创建两个客户端实例
httpClient = createHttpClient(false, null); // 无重试
httpClientWithRetry = createHttpClient(false, HttpUtils.retryInterceptor(2, 100L, true)); // 有重试
registerShutdownHook();
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
// sendRequestOkhttp 使用带重试的客户端
public static String sendRequestOkhttp(String url, String referer, boolean useAgent, String cookies) throws Exception {
// ... 其他代码不变 ...
// 使用带重试的客户端
try (Response response = httpClientWithRetry.newCall(request).execute()) {
// ... 处理响应 ...
}
}
// sendRequestDataYes 使用普通客户端
public static String sendRequestDataYes(String url, String referer, boolean useAgent, String cookies) throws Exception {
// ... 其他代码不变 ...
// 使用普通客户端(无重试)
try (Response response = httpClient.newCall(request).execute()) {
// ... 处理响应 ...
}
}
方案2:使用自定义拦截器(动态控制)
创建智能拦截器,根据请求特征决定是否重试:
public static final OkHttpClient httpClient;
static {
try {
executorService = createThreadPool();
// 创建智能重试拦截器
Interceptor smartRetryInterceptor = createSmartRetryInterceptor();
httpClient = createHttpClient(false, smartRetryInterceptor);
registerShutdownHook();
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
/**
* 智能重试拦截器:根据请求特征决定是否重试
*/
private static Interceptor createSmartRetryInterceptor() {
return chain -> {
Request originalRequest = chain.request();
// 判断是否为 DataYes 请求(根据 URL 或其他特征)
boolean isDataYesRequest = originalRequest.url().toString().contains("datayes") ||
originalRequest.header("Authorization") != null;
// 如果是 DataYes 请求,不重试
if (isDataYesRequest) {
return chain.proceed(originalRequest);
}
// 其他请求使用重试逻辑
return HttpUtils.retryInterceptor(2, 100L, true).intercept(chain);
};
}
方案3:使用请求标记(最灵活)
通过请求标签来控制重试行为:
public static final OkHttpClient httpClient;
static {
try {
executorService = createThreadPool();
// 创建条件重试拦截器
Interceptor conditionalRetryInterceptor = createConditionalRetryInterceptor();
httpClient = createHttpClient(false, conditionalRetryInterceptor);
registerShutdownHook();
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
/**
* 条件重试拦截器
*/
private static Interceptor createConditionalRetryInterceptor() {
return chain -> {
Request originalRequest = chain.request();
// 检查请求标签
Boolean enableRetry = originalRequest.tag(Boolean.class);
if (enableRetry != null && !enableRetry) {
// 明确禁用重试,直接执行
return chain.proceed(originalRequest);
}
// 默认启用重试
return HttpUtils.retryInterceptor(2, 100L, true).intercept(chain);
};
}
// sendRequestOkhttp - 启用重试(默认)
public static String sendRequestOkhttp(String url, String referer, boolean useAgent, String cookies) throws Exception {
// ... 构建请求 ...
Request request = requestBuilder.build(); // 不设置标签,使用默认重试
try (Response response = httpClient.newCall(request).execute()) {
// ... 处理响应 ...
}
}
// sendRequestDataYes - 禁用重试
public static String sendRequestDataYes(String url, String referer, boolean useAgent, String cookies) throws Exception {
// ... 构建请求 ...
// 添加标签禁用重试
Request request = requestBuilder
.tag(Boolean.class, false) // 明确禁用重试
.build();
try (Response response = httpClient.newCall(request).execute()) {
// ... 处理响应 ...
}
}
方案4:使用不同的拦截器配置
public static final OkHttpClient httpClient;
private static final Interceptor retryInterceptor = HttpUtils.retryInterceptor(2, 100L, true);
static {
try {
executorService = createThreadPool();
httpClient = createHttpClient(false, null); // 不添加全局重试拦截器
registerShutdownHook();
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
// 为特定请求手动添加重试
public static String sendRequestOkhttp(String url, String referer, boolean useAgent, String cookies) throws Exception {
// ... 构建请求 ...
// 为这个请求创建临时客户端(带重试)
OkHttpClient clientWithRetry = httpClient.newBuilder()
.addInterceptor(retryInterceptor)
.build();
try (Response response = clientWithRetry.newCall(request).execute()) {
// ... 处理响应 ...
}
}
// sendRequestDataYes 使用原始客户端(无重试)
public static String sendRequestDataYes(String url, String referer, boolean useAgent, String cookies) throws Exception {
// ... 构建请求 ...
try (Response response = httpClient.newCall(request).execute()) {
// ... 处理响应 ...
}
}
推荐使用方案1
方案1 是最简单清晰的:
-
代码意图明确
-
性能最佳(无需运行时判断)
-
易于维护和调试
-
符合单一职责原则
选择哪种方案取决于你的具体需求:
-
如果两种请求模式固定,用方案1
-
如果需要动态控制,用方案3
-
如果根据URL特征区分,用方案2
浙公网安备 33010602011771号