Обработчик ответа HttpClient всегда возвращает закрытый поток - PullRequest
1 голос
/ 01 июня 2010

Я новичок в разработке Java, поэтому, пожалуйста, потерпите меня. Кроме того, я надеюсь, что я не чемпион tl; dr :).

Я использую HttpClient , чтобы делать запросы через Http (дух!), И я заставил его работать для простого сервлета, который получает URL в качестве параметра строки запроса. Я понял, что мой код может использовать некоторый рефакторинг, поэтому я решил сделать свой собственный HttpResponseHandler, чтобы очистить код, сделать его многоразовым и улучшить обработку исключений.

У меня сейчас что-то вроде этого:

public class HttpResponseHandler implements ResponseHandler<InputStream>{

    public InputStream handleResponse(HttpResponse response)
            throws ClientProtocolException, IOException {

        int statusCode = response.getStatusLine().getStatusCode();
        InputStream in = null;

        if (statusCode != HttpStatus.SC_OK) {
            throw new HttpResponseException(statusCode, null);
        } else {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                in = entity.getContent();
                // This works
                // for (int i;(i = in.read()) >= 0;) System.out.print((char)i); 
            }
        }
        return in;
    }
}

И в методе, где я делаю фактический запрос:

HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(target);
ResponseHandler<InputStream> httpResponseHandler = new HttpResponseHandler();
try {
    InputStream in = httpclient.execute(httpget, httpResponseHandler);
    // This doesn't work
    // for (int i;(i = in.read()) >= 0;) System.out.print((char)i);     
    return in;
} catch (HttpResponseException e) {
throw new HttpResponseException(e.getStatusCode(), null);
}

Проблема в том, что входной поток, возвращаемый из обработчика, закрыт . Я понятия не имею, почему, но я проверил это с отпечатками в моем коде (и нет, я не использовал их оба одновременно :). В то время как первая печать работает, другая выдает ошибку закрытого потока.

Мне нужно InputStreams, потому что все мои другие методы ожидают InputStream, а не String. Кроме того, я хочу, чтобы можно было получать изображения (или, возможно, файлы других типов), а не только текстовые файлы.

Я могу легко обойти это, отказавшись от обработчика ответа (у меня есть рабочая реализация, которая его не использует), но мне довольно любопытно следующее:

  1. Почему делает то, что делает?
  2. Как мне открыть поток, если что-то закрывает его?
  3. В любом случае, как правильно это сделать:)?

Я проверил документы и не смог найти ничего полезного по этому вопросу. Чтобы немного сэкономить на Google, вот Javadoc и учебник HttpClient (Раздел 1.1.8 - Обработчики ответов).

Спасибо
Alex

Ответы [ 2 ]

5 голосов
/ 01 июня 2010

Он закрывает поток, потому что ResponseHandler должен обрабатывать весь ответ. Даже если вы получаете открытый поток, он должен быть в конце потока.

Поток закрывается вызовом BasicConttipEntity в ConsumerContent (), чтобы вы больше не читали из потока.

В вашем случае вам не нужен ResponseHandler.

1 голос
/ 01 июня 2010

Автоматическое управление ресурсами, которое вызывается, закрывает поток для вас, чтобы убедиться, что все ресурсы освобождены и готовы к следующей задаче.

Если вам нужны потоки, лучше всего скопировать их в ByteArray и вернуть ByteArrayInputStream, если содержимое относительно скромное.

Если содержимое не скромное, вам придется управлять ресурсами самостоятельно, а не ResponseHandler.

...