JSP out 기본 객체
JSP 페이지에서 사용할 수 있는 기본 객체들 중 out 객체에 대해서 알아보도록 하겠습니다.
JSP 페이지에 작성된 내용들은 최종적으로 출력 결과를 생성하여 클라이언트(브라우저) 측으로 전송(출력)하게 되는데, 이때 출력은 out 객체를 통해 하게됩니다. 표현식으로 작성한 출력문과 JSP 페이지에서 보이는 단순 HTML 태그 및 텍스트들도 서블릿으로 변환되는 시점에서는 out객체의 출력 메서드를 통해 출력되는 형태로 변환됩니다.

실제로 JSP가 변환된 Servlet 클래스를 보면 다음과 같은 코드들을 볼 수 있으며, 이는 규칙에 따라 변환된 것입니다.
자세한 내용은 다음 링크를 참고합니다. -> [서블릿/JSP] JSP가 Servlet으로 변환되는 과정 및 규칙 
1
2
3
4
out.println("<html>");                                                                    
out.println("<head>");
....
out.println("</html>");
cs




out 기본 객체를 직접 사용하는 경우
out 객체는 기본 객체이므로 특별히 선언 하지 않고 JSP 내부에서 사용할 수 있습니다. 이는 서블릿으로 변환될 때 내부적으로 out 객체를 생성해주기 때문에 가능한 것입니다.

그렇다면 어떤 경우에 out객체를 이용해 결과를 직접 출력할까요?
다음의 예를 보면 스크립트릿과 표현식을 통해 반복문을 돌리면서 홀수롸 짝수로 구분하여 출력하고 있습니다.
1
2
3
4
5
6
7
8
<% for(int cnt=1; cnt <= 10; cnt++){                                                     
     if(cnt % 2 == 0){ 
%>
     짝수 = <%= cnt %><br> 
<%   }else%> 
     홀수 = <%= cnt %><br> 
<%   } 
   }%> 
cs


표현식과 스크립트릿이 서로 뒤엉켜 소스를 분석하기 매우 어렵습니다.
하나의 스크립트릿 안에서 out객체로 출력하니 매우 소스가 깔끔해집니다.
1
2
3
4
5
6
7
8
9
<%                                                                                        
for(int cnt=1; cnt <= 10; cnt++){ 
     if(cnt % 2 == 0){ 
           out.println("짝수 = " + cnt + "<br>"); 
     }else
           out.println("홀수 = " + cnt + "<br>"); 
     }
}
%>
cs



out 객체의 출력 메서드
out 객체는 출력 메서드 및 출력 버퍼 관련 메서드를 사용할 수 있습니다.

메서드
리턴 타입
설명
print(String text)
void
html 태그나 단순 텍스트 등의 문자열을 출력합니다.
println(String text)
void
html 태그나 단순 텍스트 등의 문자열을 출력합니다. 다만 마지막에 줄바꿈 문자(\r\n)를 추가하여 출력합니다.
주의! <br>태그를 출력하는 것이 아닙니다.
newLine()
void
줄바꿈 문자(\r\n)를 출력합니다.
주의! <br>태그를 출력하는 것이 아닙니다.


out 객체의 버퍼 관련 메서드
out 객체는 버퍼 관련 메서드를 제공합니다. JSP 페이지에서는 page 디렉티브 속성으로 buffer 관련 속성들이 존재하는데, 실제로 이러한 속성들은 내부적으로 out객체가 사용하는 출력버퍼를 제어하기 위한 속성들입니다.
자세한 내용은 다음의 링크를 참조합니다. ->  [서블릿/JSP] JSP 출력 버퍼란 
메서드
리턴 타입
설명
getBufferSize()
int
버퍼의 크기를 구합니다.
getRemaining()
int
현재 버퍼의 남은 공간의 크기를 구합니다.
clear()
void
버퍼의 내용을 비웁니다.
버퍼를 flush() 한 이후에 사용하면 IOException이 발생됩니다.
clearBuffer()
void
버퍼의 내용을 비웁니다.
버퍼를 flush() 한 이후에 사용해도 IOException이 발생되지 않습니다.
flush()
void
현재 버퍼에 출력된 내용들을 클라이언트로 전송합니다.
isAutoFlush()
boolean
버퍼가 가득 찬 경우에 자동으로 flush() 할지의 여부가 리턴됩니다.
자동 flush인 경우 true를 리턴합니다.





response.getWriter() 로 얻은 출력 스트림과 out 객체의 차이점
JSP에서는 여럭지 기본 객체 중 응답과 관련된 response 객체가 있습니다.
이 객체는 javax.servlet.http.HttpServletResponse 타입으로 서블릿 클래스 작성시 데이터를 출력할 때 response.getWriter() 를 통해 PrintWriter를 얻기 위한 클래스였습니다.

JSP의 기본 객체이기 때문에 JSP 페이지에서도 response.getWriter() 를 통해 PrintWriter를 얻을 수 있는데, 문제는 이렇게 얻어온 PrintWriter와 out 기본 객체를 동시에 사용하는 경우입니다.
다음의 예제를 보면 response 객체를 통해 얻은 PrintWriter 객체와 out 기본객체 둘을 모두 이용하여 클라이언트측에 결과를 출력하고 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%                                                                                        
PrintWriter out2 = response.getWriter();
out2.println("for문 시작 전<br>");
 
 
for(int cnt=1; cnt <= 10; cnt++){
     if(cnt % 2 == 0){
           out.println("짝수 = " + cnt + "<br>");
     }else{
           out.println("홀수 = " + cnt + "<br>");
     }
}
 
 
out2.println("for문 종료 후<br>");
%>
cs


결과는 예상과 너무 다르게도 PrintWriter로 출력한 내용이 먼저 출력 되었고, out 기본 객체로 출력한 내용이 나중에 출력되었음을 알 수 있습니다.



왜 이런 일이 발생한 것일까요?
이는 클라이언트측(브라우저) 와 서버간에 연결된 출력 스트림(통로)가 두 개 생겼기 때문에 발생한 문제입니다.

response 객체를 통해 만든 PrintWriter 객체와 out 기본객체 두개의 출력 스트림이 생성 되었는데, 이때 out 객체는 javax.servlet.jsp.JspWriter타입 객체입니다.

그런데 이 둘의 차이는 버퍼의 사용 여부입니다. JspWriter의 경우 기본적으로 버퍼에 내용을 출력해서 모아두고 나중에 출력하지만 PrintWriter 객체는 버퍼를 거치지 않고 곧바로 출력합니다. 따라서 PrintWriter의 출력 내용이 먼저 브라우저로 출력된 것입니다.



이렇게 브라우저와 연결된 두 개의 출력 스트림을 동시에 사용하게 되면 문제가 발생할 수 있으므로 특별한 이유가 없다면 PrintWriter를 사용하는 것은 권장하지 않습니다.


블로그 이미지

도로락

IT, 프로그래밍, 컴퓨터 활용 정보 등을 위한 블로그

,