2016-09-07 109 views
0

如何使用InputStream讀取HTTP請求?我用這樣來閱讀:如何正確讀取http請求?

InputStream in = address.openStream(); 
BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
StringBuilder result = new StringBuilder(); 
String line; 
while((line = reader.readLine()) != null) { 
    result.append(line); 
} 
System.out.println(result.toString()); 

reader.readLine()可能被阻止,因爲沒有保證null線將到達。當然,我可以讀Content-Length頭,然後在一個循環中讀取請求:

for (int i = 0; i < contentLength; i++) { 
       int a = br.read(); 
       body.append((char) a); 
    } 

但如果內容長度設置得過大(我想這可以手動設置目的),br.read()將被阻止。 我嘗試從InputStream中像這樣直接讀取的字節:

byte[] bytes = getBytes(is); 

public static byte[] getBytes(InputStream is) throws IOException { 

      int len; 
      int size = 1024; 
      byte[] buf; 

      if (is instanceof ByteArrayInputStream) { 
       size = is.available(); 
       buf = new byte[size]; 
       len = is.read(buf, 0, size); 
      } else { 
       ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
       buf = new byte[size]; 
       while ((len = is.read(buf, 0, size)) != -1) 
       bos.write(buf, 0, len); 
       buf = bos.toByteArray(); 
      } 
      return buf; 
      } 

但它永遠等待。做什麼?

+0

爲什麼不能保證能夠達到'null'行?根據文檔,如果已經到達流的末尾,它將返回'null'。所以如果連接被關閉,你會在讀完最後一行後得到空值。 –

+0

我可以達到的第一個空行是頭和請求體之間的分隔符(如表單數據)。但身體後面沒有空線。做什麼? – Tony

+0

也許你得到一個空的身體請求? –

回答

2

如果你正在實現HTTP服務器,你應該根據HTTP規範檢測請求的結束。 Wiki - https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

首先,您應該閱讀請求行,它始終是單行。 然後閱讀所有請求標題。你閱讀它們,直到你有一個空行(即兩行結尾 - <CR><LF>)。

之後,你有一個狀態欄和標題,你應該決定你需要閱讀的身體或沒有,因爲不是所有的請求可能有身體 - summary table

然後,如果你需要一個身體,你應該分析你的頭(你已經得到)並獲得Content-Length。如果是 - 只要從指定的流中讀取儘可能多的字節。 當內容長度缺失時,長度以其他方式確定。分塊傳輸編碼使用塊大小爲0來標記內容的結尾。無內容長度的身份編碼將讀取內容,直到套接字關閉。

-1

創建一個擴展HttpServletRequestWrapper的請求包裝器,它將覆蓋getInputStream(),該getInputStream()返回ServletInputStream,該ServletInputStream具有安全讀取方法。試試

+0

它與servlet無關。 – Tony