Периодически неполный ответ с использованием Apache HttpClient 3.0.1 - PullRequest
3 голосов
/ 01 августа 2009

Я озадачен этим, поэтому я подумал, что если кто-нибудь из вас сталкивался с этим, так как разработка HttpClient - это немного искусства.

Проблема, с которой я сталкиваюсь, заключается в следующем: приложение использует библиотеку Java Apache HttpClient для связи с сервером в той же сети компании. В большинстве случаев это работает без проблем, но иногда мы видим множество исключений, вызванных неполными ответами: все они пропускают последние три символа закрывающего тега, поэтому анализатор в клиенте жалуется. Это длится от 5 до 10 минут, а затем уходит.

Я не смог повторить эту проблему локально, и я убедился, что ответ полностью написан сервером. Клиент получает содержимое ответа с помощью метода getResponseBodyAsStream () PostMethod, но он вызывается только один раз. Может быть, он должен циклически вызывать этот метод, пока он не станет нулевым для того редкого случая, когда ответ буферизуется?

Буду признателен за любой вклад.

Редактировать: сервер пишет заголовок длины содержимого и корректно сбрасывается, а на клиенте данные считываются в строку с:

//method is a PostMethod, client is a HttpClient
client.executeMethod(hostconfig, method); 

InputStream is = method.getResponseBodyAsStream();
String response = null;

try {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();    
    byte[] buf = new byte[1024];
    int len;

    while ((len = is.read(buf)) > 0) {
        bos.write(buf, 0, len);
    }

    response = new String(bos.toByteArray(), "UTF-8");

} ... // closing try block

Ответы [ 2 ]

1 голос
/ 30 октября 2009

Я тоже столкнулся с этой проблемой. Эта проблема появилась только после изменения URL с локального на публичный.

Я нашел пару решений ...

Первое найденное мной «решение» состояло в том, чтобы выполнить Thread.sleep (1000) перед началом процесса чтения. Я думаю, что это приводит к заполнению буфера перед попыткой чтения. (Я знаю, что это не имеет смысла, поскольку read () заявляет, что блокируется до тех пор, пока данные не станут доступны, но, к сожалению, метод read иногда думает, что он достиг конца раньше, чем ожидалось) Это больше похоже на уродливый патч, так что я продолжаю искать ...

Второй и лучший вариант - использовать метод readLine () из BufferedReader. Этот метод правильно реализует процесс чтения. Я не читал исходный код readLine, но думаю, что мы могли бы найти решение нашей проблемы там.

Привет.

1 голос
/ 01 августа 2009

Правильно ли установлены заголовки длины содержимого сервера? Я не уверен на 100%, уважает ли Commons-HttpClient их или нет, но это легко можно сделать. Я не могу придумать причину, по которой вам нужно было бы повторно вызывать getResponseBodyAsStream.

Также возможно, что ваш код для чтения потока делает ложные предположения. Возможно, мы увидим фрагмент того, как вы читаете данные, чтобы убедиться, что вы действительно правильно читаете весь поток? Некоторые распространенные ошибки кодирования могут привести к чтению только до буферизованной суммы (что приведет к случайным сбоям).

Кроме этого, трудно сказать ... мы регулярно используем Commons HttpClient без схожих симптомов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...