Apache httpClient повторяет запрос POST, игнорируя тайм-ауты - PullRequest
0 голосов
/ 15 октября 2018

В настоящее время я пытаюсь создать службу OSGi, которая отправляет запрос POST в определенный API.Этот API используется для проверки на вирусы файла, который содержится в теле запроса (JSON) в виде строки Base64.Для этого я использую Apache HttpClient, содержащийся в Adobe AEM uberjar v6.4.0

Моя текущая реализация работает нормально для файлов меньшего размера (<2 МБ), но по мере увеличения размера файлов поведение становится странным: <strong>Когда я загружаю файл размером 9 МБ, запрос выполняется в течение ~ 1 минуты, затем получает HTTP400 в качестве ответа и затем повторяет запрос 7 раз.

Я пытался использовать тайм-аут с запросом.Если время ожидания меньше 60 000 мс, возникает исключение TimeoutException, если оно превышает 60 000 мс, я получаю неверный запрос HTTP400.Я полагаю, что последний является ошибкой API, которую я должен уточнить.

Однако в обоих случаях после возникновения исключения httpClient повторяет запрос, и с тех пор я не смог этого предотвратить.Я борюсь со многими устаревшими "HowTo's" в сети, и теперь я здесь.

Я немного сократил код, так как он какой-то большой (в основном удаляя отладочные сообщения и некоторые "если ...вернуть ложь "в начале).Мой код:

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 и создает JSON, необходимый для вызова API.«valuResponse ()» также читает InputStream, преобразует его в JSON и проверяет свойство с именем «Status»: «Clean».

Буду признателен за любые подсказки о том, почему этот запрос повторяется снова и сноваснова.

/ edit: До сих пор я обнаружил, что Apache httpClient имеет некоторый механизм по умолчанию, который повторяет запрос в случае IOException - вот что я получаю здесь.Тем не менее, я не нашел решения о том, как отключить эти повторные попытки.

...