2011-06-02 74 views
5

我正在使用Apache HttpClient获取一个页面,我想将服务器应答的http正文存储到一个字符串中,以便我可以操纵此字符串并打印到控制台。Java中的Apache HttpClient,instream.toString = org.apache.http.conn.EofSensorInputStream

不幸的是运行此方法时,我得到这个消息发回:

17:52:01,862 INFO Driver:53 - fetchPage STARTING 
17:52:07,580 INFO Driver:73 - fetchPage ENDING, took 5716 
[email protected] 

的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; 
} 
+6

最关键的事情要理解此处是'的toString()'上'的InputStream '不是一种将其内容作为“String”读取的方法,而是获取对象本身的简单字符串表示。通常(包括在这种情况下)一个'InputStream'没有它可以提供的有用的字符串表示,所以它只使用默认的'Object.toString()'。 – ColinD 2011-06-02 16:17:02

回答

10

您正在呼吁InputStream中的toString后,已经通读。你需要从字节数组中创建你的字符串。更简单的方式来获得内容的字符串版本是使用EntityUtils.toString(HttpEntity)

确切IMPL会是什么样子:

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; 
} 
+0

如果我在'return EntityUtils.toString(entity)'之前加上'long elapsedTimeMillis = System.currentTimeMillis() - start;',那么程序的运行时间约为1300ms,如果我在'String result = EntityUtils.toString(entity);'然后'返回结果'大约需要5500ms。你知道这是为什么吗? – 2011-06-02 16:19:15

+2

@Jack:可能是因为客户端不必在收到实体的位置收到服务器发送的所有数据。创建字符串需要实际读取服务器发送的所有内容。 – ColinD 2011-06-02 16:42:10

+1

@Jack Murphy:EntityUtils.toString(实体)正在读取流。客户尚未收到所有数据。你会希望后者获取转移的时间。 – Joshua 2011-06-02 16:55:12