2016-09-07 2 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()

이 차단 될 수 있습니다. 물론 나는 콘텐츠 길이 헤더를 읽을 수 있습니다 다음 루프에서 요청을 읽을 : 콘텐츠 길이가 (나는이 목적을 위해 수동으로 설정할 수있을 것 같아요) 너무 큰 설정되어있는 경우

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'을 반환합니다. 따라서 연결이 닫히면 마지막 줄을 읽은 후 null이 반환됩니다. –

+0

내가 도달 할 수있는 첫 번째 null 줄은 머리글과 머리글 사이의 구분 기호로 양식 데이터와 같습니다. 그러나 시체 뒤에 null 줄이 없습니다. 뭐라구? – Tony

+0

빈 몸으로 요청을받을 수 있습니까? –

답변

2

HTTP 서버를 구현하는 경우 HTTP 사양에 따라 요청의 끝을 감지해야합니다. Wiki - https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol

우선 요청 줄을 읽어야합니다. 항상 한 줄입니다. 그런 다음 모든 요청 헤더를 읽으십시오. 빈 줄 (예 : 두 줄 끝 - <CR><LF>)이 생길 때까지 읽습니다.

당신은 당신이 결정해야합니다 상태 라인과 헤더를 한 후에는 몸을 읽을 수 없거나 모든 요청이 몸있을 수 있기 때문에 필요합니까 - 당신이 몸을 필요로하는 경우, 당신은 당신의 헤더를 분석해야한다, 그런 summary table

을 (이미 가지고있는) Content-Length를 얻습니다. 지정되고있는 경우는, 스트림로부터 지정된 수만큼의 바이트를 읽어들입니다. Content-Length가 누락되면 길이는 다른 방법으로 결정됩니다. 청크 분할 전송 인코딩은 청크 크기를 0으로 사용하여 콘텐츠의 끝을 표시합니다. Content-Length가없는 ID 인코딩은 소켓이 닫힐 때까지 내용을 읽습니다.

-1

HttpServletRequestWrapper를 확장하는 요청 랩퍼를 작성하십시오. 그러면 getInputStream()이 대체되어 안전한 읽기 메소드가있는 ServletInputStream을 리턴합니다. 시도해보십시오

+0

서블릿과 관련이 없습니다. – Tony