2016-09-07 5 views
0

InputStreamを使用してHTTPリクエストを読み取る方法は? nullラインに到達するという保証がないため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()は、ブロックされる可能性があります:私はこのようにそれを読むために使用しました。もちろん、私は、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

まず、リクエストラインを読む必要があります。常に1行です。 次に、すべての要求ヘッダーを読み取ります。空の行(2行の末尾 - <CR><LF>)があるまで、それらを読み込みます。

あなたが決めるべきステータス行とヘッダを持った後、あなたが身体を読み取るために、あるいはまったくないすべての要求は、身体持っている可能性があるため、必要があります - あなたは体が必要な場合、あなたはあなたのヘッダーを解析する必要があり、その後summary table

を(あなたはすでに持っています)、Content-Lengthを取得します。そうであれば、ストリームから指定されたバイト数だけ読み込みます。 Content-Lengthが指定されていない場合、長さは他の方法で決定されます。チャンク転送符号化は、チャンクサイズ0を使用してコンテンツの終了をマークします。 Content-LengthなしのIDエンコーディングは、ソケットが閉じられるまでコンテンツを読み取ります。

-1

HttpServletRequestWrapperを拡張するリクエストラッパーを作成します。このラッパーはgetInputStream()をオーバーライドし、安全な読み取りメソッドを持つServletInputStreamを返します。試してください

+0

サーブレットとは関係ありません。 – Tony

関連する問題