2014-03-29 1 views
2

좀 더 잘 이해하기 위해 HttpServlet에 약간의 실험을했습니다. 요청이 들어오는 시나리오를 만들고 싶었고 응답을 가능한 한 빨리 보내야하고 나중에 서블릿에서 더 많은 작업을해야했습니다. 현재의 이해에서 doGet 또는 doPost 메소드가 리턴 될 때만 응답을 클라이언트로 송신해야합니다. 그러나 나의 예에서 서블릿의 명령 처리 내에서 응답은 이미 클라이언트로 되돌려 보내집니다. 그래서 내가 기대하지 않을 때 이미 돌아 왔습니다.Java - HttpServlet : 응답이 클라이언트에 언제 전송됩니까?

protected void processRequest(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 
     try { 
      Thread.sleep(500); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(DisplayHeader.class.getName()).log(Level.SEVERE, null, ex); 
     } 

     response.setContentType("text/plain; charset=ISO-8859-1"); 
     response.setStatus(HttpServletResponse.SC_FORBIDDEN); 
     final StringWriter sw = new StringWriter(); 
     PrintWriter out = new PrintWriter(sw); 
     //TODO most be implemented SynchronizedStatusCodeDimo 
     out.println("StatusCode=0"); 
     out.println("StatusText=Accepted"); 
     out.println("paymentType=PaymentXY"); 
     out = response.getWriter(); 
     out.print(sw.toString()); 
     out.flush(); 
     out.close(); 

     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(DisplayHeader.class.getName()).log(Level.SEVERE, null, ex); 
     } } 

여기에서 무슨 일이 일어나고 있는지, 방화범을 통해 나는 510ms 후에 응답을 받았습니다. 나는 잠들기 때문에 1500ms 이상을 필요로한다고 생각했습니다. 내 이해는이 게시물을 기반으로했습니다 : Link

+2

여기가 무슨 문제입니까? 그 플러시() 플러시? 또는 닫기()가 닫힙니다. 왜 이렇게 놀라운가? – EJP

+0

request1에 대한 성공 콜백 후 클라이언트에서 request2를 스폰 할 수 없습니까? 그리고 요청 2 request1 응답을 기반으로 추가 처리 할 수 ​​있습니다 .. –

+0

어쩌면 아무 문제가 전혀, 내가 처음에만 잘못있어 응답을 모두 서블릿에서 완료된 후 (그래서 doGet/doPost가 반환되었습니다.) 처리 중일 때는 여기가 아닙니다. – fryk9

답변

4

HttpServletResponse은 서블릿 컨테이너 (Tomcat, Jetty 등)에서 제어합니다.

response에 쓸 경우 서블릿 컨테이너는 정의 된 버퍼 크기 (예 : 9000 바이트 이후의 Tomcat) 이후에 자동으로 response을 플러시합니다. 일반적으로 구성 할 수 있습니다 (Tomcat에서 매개 변수 socketBuffer). 혼자서 제어하지 않으면 작동하는 방식입니다.

귀하가 직접 응답을 제어하면 response.flush()으로 전화를 걸어 응답이 클라이언트로 전송됩니다. Tomcat에서 9000 바이트 이상을 기록한 경우 자동으로 응답이 전송됩니다 (중간에 모두 표시됨).

(내 나쁜 영어 변명)

+0

감사합니다. 그러나 out.close()는 내 예제에서 응답을 보내도록합니다. out.close() 줄을 제거하고 out.flush() 만 사용하면 응답은 1500ms 후에 전송되므로 응답을 보내기 전에 두 절전 모두 처리됩니다. – fryk9

+0

올바르지 않습니다. 첫 번째 경우에는 500ms (out.flush() 이후) 이후에 응답이 시작되고 스트림을 닫으면 500ms 후에도 응답이 완료됩니다. 두 번째 서버는 500ms 후 (out.flush() 후에) 응답을 시작하지만 서블릿 컨테이너가 스트림을 모두 닫은 후 1500ms 후에 응답이 끝납니다. 당신은 방화범이들 속에서 이것을보아야합니다. – drkunibar

+0

나는 그것이 완전히 이해된다는 것을 이해합니다. 감사. – fryk9

관련 문제