我目前正在尝试构建OSGi服务,该服务将POST请求发送到已定义的API。该API用于病毒扫描包含在请求正文(JSON)中作为Base64字符串的文件。 为此,我正在使用Adobe AEM uberjar v6.4.0中包含的Apache HttpClient
我当前的实现适用于较小的文件(<2 MB),但是随着文件大小的增大,行为变得奇怪: 当我上传一个9 MB的文件时,请求将执行约1分钟,然后获得HTTP400作为响应,然后重试请求7次。
我尝试对请求使用超时。如果超时小于60.000ms,则抛出TimeoutException,如果大于60.000ms,则会收到HTTP400错误请求。我想后者是我需要澄清的API错误。
但是,在两种情况下,在引发异常之后,httpClient都会重试该请求,此后我一直无法阻止。我在网上与许多不推荐使用的“ HowTo's”苦苦挣扎,现在我在这里。
我已经将代码缩短了一点,因为它有点大(主要是删除调试消息和一些开头的“ if ... return 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的情况下重试请求-这就是我得到的。不过,我还没有找到有关如何停用这些重试的解决方案。