2009-07-31 2 views
3

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

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

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

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

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

//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 
+0

Редактировать: Как со многими трудно найти ошибки, проблема, похоже, связана со специальными символами (европейские символы с акцентом, немецкие длинные и т. Д.). После того, как сообщения были нормализованы для удаления этих символов, ошибки были остановлены. – Munir

+0

Наличие аналогичной проблемы. Точно такой же URL. Используя браузер/Curl, дайте мне полные данные. Но, Httpclient получает неполный результат ...! – thinkanotherone

ответ

1

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

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

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

+0

Эй, спасибо за ответ. Я редактировал вопрос, чтобы уточнить.Сервер правильно пишет заголовки и выполняет промывку, и я добавил код, который читается из Stream. Я также заглянул в конфигурацию HttpClient, которая используется клиентом, и единственное, что на меня набросилось, - это явная настройка параметра Linger-on-timeout на 0 (отключено). – Munir

1

Я тоже сталкивался с этой проблемой. Эта проблема появилась только после изменения URL-адреса с localhost на общедоступную.

Я нашел несколько решений ...

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

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

Приветствия.

Смежные вопросы