2011-06-02 72 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