상세 컨텐츠

본문 제목

JSP 1.0 : include --> forward

프로그래밍/JAVA

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

본문

제목 : JSP 1.0 : include --> forward
글쓴이: 이원영(javaservice) 2001/03/11 00:21:42 조회수:2944 줄수:106
> WAS3.5.2에서...
> include action된 페이지내에서
> 다시 forward를 하니까... 출력스트림이 이미 작성되어 컴파일에러가 납니다.
>
> 똑같은 소스로,WAS3.5.0에서는 문제가 없는데 말입니다.
> 
> 어떻하죠....
>
> 현재로서는 대안으로 forward를 include action으로 바꾸어 사용하고 있습니다.
> WAS3.5.2가 더 불안정한 것 같네요...
>

[a.jsp]
----------------------------------
a.jsp 입니다.
<jsp:include page="b.jsp" />
----------------------------------

[b.jsp]
----------------------------------
b.jsp 입니다.
<jsp:forward page="c.jsp" />
----------------------------------

[c.jsp]
----------------------------------

c.jsp 입니다.
----------------------------------

위와 같은 상황에서 a.jsp 를 부르면 WebSphere JSP 1.0 에서 다음과 같은 에러가
발생하게 됩니다.

java.lang.IllegalStateException: ERROR: Cannot forward. Writer or Stream already
obtained.
	at java.lang.RuntimeException.<init>(RuntimeException.java:49)
	at java.lang.IllegalStateException.<init>(IllegalStateException.java:47)
	at com.ibm.servlet.engine.webapp.WebAppRequestDispatcher.forward(WebAppReque
    stDispatcher.java:99)
	at org.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:357)
	at D_0003a.WebSphere.AppServer.hosts.d_00025fault_0005fhost.AppServerWebApp.
    web._b_2E_jsp_jsp_1._jspService(_b_2E_jsp_jsp_1.java:85)
	at com.sun.jsp.runtime.HttpJspBase.service(HttpJspBase.java:175)

이것은 웹스피어의 버그가 아니라, JSP 스펙 1.0 준수하기 때문에 발생하는 당연한
결과 입니다.

JSP 1.0 Specification 2.13.4 <jsp:include>에 보면, 아래와 같이 기술되어 있습니다.

"If the page output is buffered then the buffer is flushed prior to the inclusion."

또한, 2.13.5 <jsp:forward> 에 보면, 아래처럼 기술되어 있습니다.
"If the page output was unbuffered and anything has been written to it, an attempt
to forward the request will result in an IllegalStateException."

즉, a.jsp 에서 "a.jsp입니다" 라는 문자열들이 output buffer 에 buffering 되어 있는
상태에서 b.jsp 를 include 하려면, buffer 에 저장된 내용을 "flushing"시켜야
합니다. 이 때, b.jsp 에서는 forward 를 하려면, 이미 output buffer 의 내용이
flushing 되었으니 IllegalStateException 이 발생하게 되는 거지요....

정말 이러하냐를 확인 하는 방법은 아래처럼 약간 변형하여 buffer 에 아무런 내용도
넣지 않도록 해 보면 되겠죠... a.jsp 에서 가장 첫줄 첫글자에서 부터 곧바로
b.jsp 를 include 해 보시면 되겠죠...

[a.jsp]
----------------------------------
<jsp:include page="b.jsp" />
a.jsp 입니다.
----------------------------------

[b.jsp]
----------------------------------
b.jsp 입니다.
<jsp:forward page="c.jsp" />
----------------------------------

[c.jsp]
----------------------------------

c.jsp 입니다.
----------------------------------

그 결과는 아무런 에러없이 아래와 같은 결과화면을 가져오게 됩니다.

"c.jsp 입니다. a.jsp 입니다."


PS: 여기서, "c.jsp 입니다" 외에 왜 "a.jsp 입니다"라는 문자열이 따라 왔을까요?
  이 이유는 JSP 1.0 Spec  2.13.4 <jsp:include> 에 다음과 같이 그 해답을 
  기술하고 있습니다.
  "Request processing resumes in the calling JSP, once the inclusion is 
   completed."

PS: WebSphere 3.5.0 에서 문제없이 된 것은 WebSphere 3.5.0 의 버그겠지요.
   JSP 1.0 을 준수하지 않았으니까요..

NOTE: 어쨌든, include 문장이 항상 a.jsp 에서 첫문장에 되어야 한다는 보장이
   실 프로젝트에선 존재할 수 없을 겁니다. 따라서, include  되는 JSP에서
   다시 forward 하는 구조는 바람직하지 않습니다.

NOTE: Java 를 공부하실 땐, 늘 Specification 를 읽어보는 습관을 들이세요...

이원영
javaservice@hanmail.net, lwy@kr.ibm.com

관련글 더보기