java - Apache httpClient在忽略超时时重试POST请求
问题描述
我目前正在尝试构建一个向定义的 API 发送 POST 请求的 OSGi 服务。此 API 用于对请求正文 (JSON) 中作为 Base64 字符串包含的文件进行病毒扫描。为此,我使用 Adobe AEM uberjar v6.4.0 中包含的 Apache HttpClient
我当前的实现适用于较小的文件(<2 MB),但随着文件大小变大,行为变得奇怪: 当我上传 9 MB 文件时,请求执行约 1 分钟,然后获得 HTTP400 作为响应,然后重试请求 7 次。
我尝试对请求使用超时。如果超时低于 60.000 毫秒,则会引发 TimeoutException,如果大于 60.000 毫秒,则会收到 HTTP400 错误请求。我想后者是我需要澄清的 API 错误。
但是,在引发异常后的这两种情况下,httpClient 都会重试请求,但我无法阻止这种情况发生。我正在与网络上许多已弃用的“HowTo”作斗争,现在我在这里。
我稍微缩短了代码,因为它有点大(主要是在开头删除调试消息和一些“如果...返回 false”)。我的代码:
public boolean isAttachmentClean(InputStream inputStream) throws IOException, JSONException, ServiceUnavailableException {
//prevent httpClient from retrying in case of an IOException
final HttpRequestRetryHandler retryHandler = new DefaultHttpRequestRetryHandler(0, false);
HttpClient httpClient = HttpClients.custom().setRetryHandler(retryHandler).build();
HttpPost httpPost = new HttpPost(serviceUrl);
httpPost.setHeader("accept", "application/json");
//set some more headers...
//set timeout for POST from OSGi Config
RequestConfig timeoutConfig = RequestConfig.custom()
.setConnectionRequestTimeout(serviceTimeout)
.setConnectTimeout(serviceTimeout)
.setSocketTimeout(serviceTimeout)
.build();
httpPost.setConfig(timeoutConfig);
//create request body data
String requestBody;
try {
requestBody = buildDataJson(inputStream);
} finally {
inputStream.close();
}
HttpEntity requestBodyEntity = new ByteArrayEntity(requestBody.getBytes("UTF-8"));
httpPost.setEntity(requestBodyEntity);
//Execute and get the response.
HttpResponse response = httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() != HttpServletResponse.SC_OK){
httpPost.abort();
throw new ServiceUnavailableException("API not available, Response Code was "+ response.getStatusLine().getStatusCode());
}
HttpEntity entity = response.getEntity();
boolean result = false;
if (entity != null) {
InputStream apiResult = entity.getContent();
try {
// check the response from the API (Virus yes or no)
result = evaluateResponse(apiResult);
} finally {
apiResult.close();
}
}
return result;
}
“buildDataJson()”只是读取 InputStream 并创建 API 调用所需的 JSON。“evaluateResponse()”还读取 InputStream,将其转换为 JSON 并检查名为“Status:”“Clean”的属性。
我将不胜感激有关为什么一遍又一遍地重试此请求的任何提示。
/edit:到目前为止,我发现 Apache httpClient 有一些默认机制,可以在 IOException 的情况下重试请求——这就是我在这里得到的。尽管如此,我还没有找到关于如何停用这些重试的解决方案。
解决方案
推荐阅读
- ios - Unity Codeless IAP 和 iOS:“UnityIAP:收到 0 个产品”
- mongodb - Mongo 查询失败,错误代码 13 和错误消息“未授权”
- javascript - $().html() 后无法输入空白表单文本区域;
- c# - C#松耦合访问属性值
- spring-security - 允许通过 Spring Web Security 对安全资源进行有限访问
- chatbot - 如何跟踪用户在聊天机器人上提出的问题(Microsoft Azure Bot Service)
- php - While 循环抛出关于使用数组的新索引时未定义的通知
- python - 在python中将文件放在带有编号的文件夹中
- python - 隔离日期格式的字符串部分
- sas - SAS - 循环数据