Как прочитать текстовый HTTP-ответ в строку точно так, как есть?

Следующий код использует BufferedReader для чтения из потока ответов HTTP:

final StringBuilder responseBuilder = new StringBuilder();
String line = bufferedReader.readLine();
while (line != null) {
    responseBuilder.append(line);
    responseBuilder.append('\n');
    line = bufferedReader.readLine();
}
response = responseBuilder.toString();

Но добавление '\n' к каждой строке кажется немного ошибочным. Я хочу вернуть HTTP-ответ точно как есть, а что, если после последней строки в нем нет символа возврата? В любом случае один из них будет добавлен с использованием приведенного выше кода - есть ли лучший способ?


person Steve Chambers    schedule 14.03.2013    source источник
comment
Я полагаю, вы получаете html-текст? это правильно? вы добавляете \n, потому что хотите, чтобы он был в удобочитаемой форме? потому что любой парсер должен обрабатывать ответ даже без разрывов строки   -  person Najzero    schedule 14.03.2013
comment
Да, тип контента text/xml. Для целей того, что делает система, на самом деле не обязательно, чтобы она была удобочитаемой для человека, но она регистрируется в файле журнала, поэтому по этой причине это необходимо.   -  person Steve Chambers    schedule 14.03.2013
comment
хорошо, тогда я бы рекомендовал запустить его через красивую библиотеку печати (также позаботившись об идентификации). Я думаю, что sourceforge.net/projects/jtidy было бы неплохо. Просто вбейте в него весь ответ и запросите красивую распечатку.   -  person Najzero    schedule 14.03.2013


Ответы (1)


Я хочу вернуть HTTP-ответ точно как есть

Тогда не используйте readLine() - это так просто. Вместо этого я бы предложил использовать StringWriter:

StringWriter writer = new StringWriter();
char[] buffer = new char[8192];
int charsRead;
while ((charsRead = bufferedReader.read(buffer)) > 0) {
    writer.write(buffer, 0, charsRead);
}
response = writer.toString();

Обратите внимание, что даже это не сработает, если вы ошибетесь в кодировке. Чтобы сохранить точный HTTP-ответ, вам нужно прочитать (и записать) его как бинарный поток.

person Jon Skeet    schedule 14.03.2013
comment
Чтобы сохранить точный HTTP-ответ, вам нужно прочитать байты, не опосредуя Reader, и вам также нужно знать о проблеме Content-Length. - person user207421; 14.03.2013
comment
@EJP - я столкнулся с проблемой длины содержимого, поднятой в предыдущем вопросе: stackoverflow.com/questions/14817310/ Это та же проблема, о которой вы говорите? - person Steve Chambers; 14.03.2013
comment
@EJP: согласен с бинарной стороной вещей - см. конец моего ответа. Что касается длины контента, я ожидаю, что читатель уже поступит правильно. - person Jon Skeet; 14.03.2013
comment
Какой читатель? Если ввод поступает из HttpURLConnection, все это происходит для вас, но если это сокет, это не так: вы должны прекратить чтение на Content-length, если он есть, обрабатывать фрагментированное кодирование и т. д. самостоятельно; в противном случае вы можете переполнить тело и начать чтение следующего запроса. Здесь нет доказательств того, что это такое. - person user207421; 15.03.2013