【问题标题】:Apache HttpClient in Java, instream.toString = org.apache.http.conn.EofSensorInputStreamJava 中的 Apache HttpClient,instream.toString = org.apache.http.conn.EofSensorInputStream
【发布时间】:2011-09-07 04:52:44
【问题描述】:

我正在使用 Apache HttpClient 获取一个页面,并且我想将服务器回复的 http 正文存储到一个字符串中,这样我就可以操作该字符串并将其打印到控制台。

不幸的是,在运行此方法时,我收到了这条消息:

17:52:01,862  INFO Driver:53 - fetchPage STARTING
17:52:07,580  INFO Driver:73 - fetchPage ENDING, took 5716
org.apache.http.conn.EofSensorInputStream@5e0eb724

fetchPage 类:

public String fetchPage(String part){
    log.info("fetchPage STARTING");
    long start = System.currentTimeMillis();

    String reply;

    String searchurl = URL + URL_SEARCH_BASE + part + URL_SEARCH_TAIL;

    HttpClient httpclient = new DefaultHttpClient();
    HttpGet httpget = new HttpGet(searchurl);
    HttpResponse response;
    try {
        response = httpclient.execute(httpget);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream instream = entity.getContent();
            int l;
            byte[] tmp = new byte[2048];
            while ((l = instream.read(tmp)) != -1) {
            }
            long elapsedTimeMillis = System.currentTimeMillis()-start;
            log.info("fetchPage ENDING, took " + elapsedTimeMillis);
            reply = instream.toString();
            System.out.println(reply);
            return reply;
        }
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return null;
}

【问题讨论】:

  • 这里要理解的关键是InputStream 上的toString() 不是将其内容读取为String 的方法,而是获取对象本身的简单字符串表示.通常(包括在这种情况下)InputStream 没有它可以提供的有用的字符串表示,所以它只使用默认的Object.toString()

标签: java httpclient inputstream http-get


【解决方案1】:

您在InputStream 上调用toString 在它已经读完之后。您需要从字节数组创建字符串。获取内容的字符串版本更简单的方法是使用EntityUtils.toString(HttpEntity)

具体实现如下:

import org.apache.http.util.EntityUtils;

public String fetchPage(String part){
    log.info("fetchPage STARTING");
    long start = System.currentTimeMillis();

    String reply;

    String searchurl = URL + URL_SEARCH_BASE + part + URL_SEARCH_TAIL;

    HttpClient httpclient = new DefaultHttpClient();
    HttpGet httpget = new HttpGet(searchurl);
    HttpResponse response;
    try {
        response = httpclient.execute(httpget);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            return EntityUtils.toString(entity);
        }
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return null;
}

【讨论】:

  • 如果我在return EntityUtils.toString(entity);之前添加long elapsedTimeMillis = System.currentTimeMillis()-start;,则该过程的经过时间约为1300毫秒,如果我在String result = EntityUtils.toString(entity);之后停止时间然后return result大约需要5500毫秒。你知道这是为什么吗?
  • @Jack:可能是因为客户端不必在您获取实体时收到服务器发送的所有数据。创建字符串需要实际读取服务器发送的所有内容。
  • @Jack Murphy:EntityUtils.toString(entity) 正在读取流。客户端尚未收到所有数据。您将希望后者捕获传输时间。
猜你喜欢
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-03
  • 2013-08-30
  • 1970-01-01
  • 2013-01-30
相关资源
最近更新 更多