Java: HttpComponents получает мусор Ответ от входного потока с определенного URL - PullRequest
0 голосов
/ 27 августа 2011

В настоящее время я пытаюсь заставить HttpComponents отправлять HttpRequests и получать ответ.На большинстве URL-адресов это работает без проблем, но когда я пытаюсь получить URL-адрес форума phpBB, а именно http://www.forum.animenokami.com, клиенту требуется больше времени, а responseEntity содержит отрывки более одного раза, что приводит к повреждению html-файла.

Например, метатеги содержатся шесть раз.Поскольку многие другие URL работают, я не могу понять, что я делаю неправильно.Страница работает правильно в известных браузерах, поэтому это не проблема для них.

Вот код, который я использую для отправки и получения.

        URI uri1 = new URI("http://www.forum.animenokami.com");
    HttpGet get = new HttpGet(uri1);
    get.setHeader(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:6.0) Gecko/20100101 Firefox/6.0"));
    HttpClient httpClient = new DefaultHttpClient();
    HttpResponse response = httpClient.execute(get);
    HttpEntity ent = response.getEntity();
    InputStream is = ent.getContent();
    BufferedInputStream bis = new BufferedInputStream(is);
    byte[] tmp = new byte[2048];
    int l;
    String ret = "";
    while ((l = bis.read(tmp)) != -1){
        ret += new String(tmp);
    }

Надеюсь, вы поможетемне.Если вам потребуется дополнительная информация, я постараюсь предоставить ее как можно скорее.

Ответы [ 2 ]

4 голосов
/ 27 августа 2011

Этот код полностью не работает:

String ret = "";
while ((l = bis.read(tmp)) != -1){
    ret += new String(tmp);
}

Три вещи:

  • Это преобразовывает буфер whole в строку на каждой итерации, независимо от того,о том, сколько данных было прочитано.(Я подозреваю, что это то, что на самом деле идет не так в вашем случае.)
  • Используется кодировка платформы по умолчанию, что почти никогда не является хорошей идеей.
  • В нем используется конкатенация строк в цикле,приводит к снижению производительности.

К счастью, вы можете очень легко избежать всего этого, используя EntityUtils:

String text = EntityUtils.toString(ent);

Это будет использовать соответствующую кодировку символовуказанный в ответе, если таковой имеется, или ISO-8859-1 в противном случае.(Есть еще одна перегрузка, которая позволяет вам указать, какую кодировку символов использовать, если она не указана.)

Стоит понять, что не так с вашим исходным кодом, хотя вместо просто заменив его на лучшийкод, чтобы вы не делали те же ошибки в других ситуациях.

0 голосов
/ 27 августа 2011

Это работает нормально, но я не понимаю, почему я вижу один и тот же текст несколько раз только на этом URL.

Это будет потому, что ваш клиент видит больше неполных буферов, когда он читает сокет. Чем может быть:

  • из-за узкого места в полосе пропускания сети на маршруте от удаленного сайта к вашему клиенту,
  • потому что удаленный сайт делает некоторые ненужные сбрасывания, или
  • какая-то другая причина.

Суть в том, что ваш клиент должен обратить пристальное внимание на количество байтов, считанных в буфер при вызове read, в противном случае он в конечном итоге вставит ненужную информацию. В частности, сетевые потоки не заполняют буфер.

...