상세 컨텐츠

본문 제목

Servlet/JSP에서 버퍼를 사용하는 이유

프로그래밍/JAVA

by 라제폰 2009. 1. 30. 17:55

본문

1. 헤더의 응답코드

 

200: 정상 응답을 의미. 몸통의 내용을 브라우저 창에 표시할 것을 지시
204: No Content. 몸통이 없으니, 현재 보여주고 있는 화면을 계속 유지할 것을 지시
302: Temporarily Moved. 현재 페이지를 다른 페이지로 이동시킬 것을 브라우저에 지시
404: Not Found. 요청한 자원이 존재하지 않는 자원임을 의미
500: Internal Server Error. 서버 내부 오류가 발생하였음을 의미


2. forward와 sendRedirect

 

Servlet/JSP/HTML 환경에서 현재 보고있는 페이지를 다른 페이지로 이동시키는 방법은
대표적으로 세가지가 있다.

1) javascript에서 location.href값을 변경
-> 통상 브라우저 내부캐쉬에 저장된 값을 보여준다. 캐쉬를 꺼주어야 함.

2) <jsp:forward>를 사용하거나(JSP), RequestDispatcher.forward()를 사용(Servlet)
-> 브라우저 주소창의 주소는 바뀌지 않으면서 페이지만 변경된다.

3) response.sendRedirect()를 사용
-> 브라우저 주소창의 주소가 바뀌면서 페이지도 변경된다.
-> 302 헤더 사용


3. Servlet/JSP에서 버퍼를 사용하는 이유

 

HTTP 응답은 한번에 하나의 응답코드만을 가질 수 있다. [헤더 + 몸통] 구조로 되어있기
때문에 항상 헤더가 몸통보다 앞에 오게 된다.

- Servlet/JSP 실행시 순차적으로 HTML의 내용을 client 쪽으로 내리고 있는 상태에서
이미 200(정상응답) 헤더를 브라우저에 모두 전송한 뒤 Exception이 발생할 경우
헤더 응답코드는 200에서 500으로 바뀌어야 되는 상황이 발생된다.

- response.sendRedirect() 도 마찬가지이다. 200 헤더를 보낸 상태에서 response.sendRedirect()
를 만나면 302 헤더로 변경해야 하는 상황이 발생한다.

=> 아래와 같은 에러로그 발생
--------------------------------------------------------------------------------------------------------------
[2005-10-06 18:09:51 - ERR] http://stong.cjmall.com/etv_new/itemDtlView.jsp?item_seq=1&item_code=10141868&bd_d
ate=1128524400000&prog_code=558055&bd_btime=20051006112000&shop_id=2002112507&dp_yn=
[2005-10-06 18:09:51 - ERR] ErrorPage [CJW9_7002]
java.lang.IllegalStateException: response already committed
  at weblogic.servlet.internal.ServletResponseImpl.sendRedirect(ServletResponseImpl.java:595)
  at jsp_servlet._etv_new.__itemdtlview._jspService(itemDtlView.jsp:27)
  at weblogic.servlet.jsp.JspBase._service(JspBase.java:91)
  at weblogic.servlet.jsp.JspBase.service(JspBase.java:68)
  at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:996)
  at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:419)
  at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:315)
  at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:6456
)
  at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
  at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:118)
  at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3661)
  at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2630)
  at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:219)
  at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:178)
--------------------------------------------------------------------------------------------------------------

- 직접 HTTP 302 헤더를 사용하지는 않는 <jsp:forward>나 RequestDispatcher.forward()의
경우도 약간 다르지만 비슷하다. forward시킨 페이지에서 만일 500헤더나 302헤더를 사용해야 하는
경우가 생긴다면 아직 버퍼에만 내용이 담겨있을 때는 괜찮지만, 이미 브라우저에게 버퍼의 내용을
전송해버린 뒤에는 어떻게 처리해야 할지 모르는 상태가 나타나게 된다.

------------------------------------------------------------------------

이러한 문제들을 해결하기 위해서 Servlet/JSP 에서는 버퍼를 지원하고 있다.
실제로 client 쪽으로 200헤더를 붙여서 페이지를 내리기 시작하더라도 우선적으로 모든 출력값은
내부 버퍼에만 담기고 브라우저에는 보내주지 않는 상태로 진행된다.

버퍼에 담기고 있는 상황에서 302나 500을 만나는 상황이 발생한다면 200을 버리고 해당 응답코드로
변경하고 브라우져에 보내게 된다. 모든 작업이 끝난 후 마지막으로 buffer flush 가 이루어지는 것이다.

------------------------------------------------------------------------

 

4. JSP include

 

JSP 에서 페이지 include 하는 방법은 두가지가 있다.

 

1) include 지시어 - <%@ include file="URI" %>


- static 형태로 동작 include file 변경시 전체 페이지 재 컴파일 일어남
- include file 자체도 원페이지 내부의 페이지로 인식하며 하나의 파일로 생성

 

2) JSP Action - <jsp:include page="URI" flush="true" />


- dynamic 형태로 별도로 동작하며 변경시 바로 적용됨
- 파라메타 사용 가능
- 변경된 파일만 컴파일이 일어남

 

[ 결론 ]

<%@ include file="/common/incFront.jsp" %> 를 사용할 경우

1. response.sendRedirect("XXX"); 사용금지
2. 쿠키 사용 금지

<%@ include file="/common/trxHeader.jsp" %> 를 사용할 경우에는 이와같은 현상이 발생하지 않습니다.


관련글 더보기