Apache httpClient忽略超时时重试POST请求

时间:2018-10-15 08:07:23

标签: java apache post aem

我目前正在尝试构建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的情况下重试请求-这就是我得到的。不过,我还没有找到有关如何停用这些重试的解决方案。

0 个答案:

没有答案