Использование Apache HttpClient, как установить время на запрос и ответ - PullRequest
35 голосов
/ 26 марта 2012

Мне нужно установить тайм-аут для запроса Http, который мы делаем службе (не веб-службе). Мы используем Apache HTTP Client. Я добавил эти 2 строки кода, чтобы установить время ожидания для запроса и ответа на сервис.

HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 10000);

1) В настоящее время я установил 10 секунд в качестве тайм-аута, так как я вижу, что ответ от службы почти мгновенно. Должен ли я увеличить или уменьшить сроки?

2) Что произойдет, если ответ займет более 10 секунд? Будет ли это исключение, и каким оно будет? Есть ли что-то еще, что мне нужно добавить, чтобы установить время в приведенном ниже коде.

public HashMap<String, Object> getJSONData(String url) throw Exception{
    DefaultHttpClient httpClient = new DefaultHttpClient();
    HttpParams params = httpClient.getParams();
    HttpConnectionParams.setConnectionTimeout(params, 10000);
    HttpConnectionParams.setSoTimeout(params, 10000);
    HttpHost proxy = new HttpHost(getProxy(), getProxyPort());
    ConnRouteParams.setDefaultProxy(params, proxy);
    URI uri;
    InputStream data = null;
    try {
        uri = new URI(url);
        HttpGet method = new HttpGet(uri);
        HttpResponse response = httpClient.execute(method);
        data = response.getEntity().getContent();
    }
    catch (Exception e) {
        e.printStackTrace();
    }
    Reader r = new InputStreamReader(data);
    HashMap<String, Object> jsonObj = (HashMap<String, Object>) GenericJSONUtil.fromJson(r);
    return jsonObj;
}

Ответы [ 2 ]

63 голосов
/ 01 июля 2015

Я предполагаю, что многие люди приходят сюда из-за названия и из-за того, что HttpConnectionParams API устарел.

Используя последнюю версию Apache HTTP Client, вы можете установить эти тайм-ауты, используя параметры запроса:

HttpPost request = new HttpPost(url);

RequestConfig requestConfig = RequestConfig.custom()
  .setSocketTimeout(TIMEOUT_MILLIS)
  .setConnectTimeout(TIMEOUT_MILLIS)
  .setConnectionRequestTimeout(TIMEOUT_MILLIS)
  .build();

request.setConfig(requestConfig);

Кроме того, вы также можете установить это при создании своего HTTP-клиента, используя API-интерфейс для HTTP-клиента, но вам также потребуется создать собственный менеджер соединений с пользовательской конфигурацией сокетов.

Файл примера конфигурации является отличным ресурсом, чтобы узнать о том, как настроить HTTP-клиент Apache.

35 голосов
/ 26 марта 2012

Исключения, которые вы увидите, будут ConnectTimeoutException и SocketTimeoutException.Фактические значения времени ожидания, которые вы используете, должны быть максимальным временем ожидания вашего приложения.Одно важное замечание о тайм-ауте чтения - это то, что он соответствует тайм-ауту чтения сокета.Таким образом, это не время, отведенное для получения полного ответа, а время, отведенное для чтения одного сокета.Таким образом, если имеется 4 чтения сокетов, каждое из которых занимает 9 секунд, ваше общее время чтения составляет 9 * 4 = 36 секунд.

Если вы хотите указать общее время получения ответа (включая соединение и общее чтениевремя), вы можете заключить вызов в поток и использовать для этого время ожидания потока.Например, я обычно делаю что-то вроде этого:

Future<T> future = null;
future = pool.submit(new Callable<T>() {
    public T call() {
        return executeImpl(url);
    }   
}); 

try {
    return future.get(10, TimeUnit.SECONDS);
}   
catch (InterruptedException e) {
    log.warn("task interrupted", name);
}   
catch (ExecutionException e) {
    log.error(name + " execution exception", e); 
}   
catch (TimeoutException e) {
    log.debug("future timed out", name);
}

Некоторые предположения, сделанные в приведенном выше коде: 1) это функция с параметром url, 2) она находится в классе с переменной name, 3) журнал - это экземпляр log4j, и 4) пул - это какой-то исполнитель пула потоков.Обратите внимание, что даже если вы используете тайм-аут потока, вы должны также указать тайм-аут соединения и сокета на HttpClient, чтобы медленные запросы не поглощали ресурсы в пуле потоков.Также обратите внимание, что я использую пул потоков, потому что обычно я использую это в веб-сервисе, поэтому пул потоков является общим для нескольких потоков Tomcat.Ваша среда может отличаться, и вы можете предпочесть просто создавать новый поток для каждого вызова.

Кроме того, я обычно вижу тайм-ауты, установленные через функции-члены параметров, например:

params.setConnectionTimeout(10000);
params.setSoTimeout(10000);

Но, возможно, ваш синтаксис также работает (не уверен).

...