[JSP] jsp:include flush속성, jsp 출력 버퍼, include 된 페이지에서 헤더,쿠키 추가 안되는 현상. 코드를 만들어서 확인

2020. 6. 30. 16:50웹/JSP

Jsp 를 사용하다보면 include 로 페이지를 포함시키는 경우가 있는데 이때 flush 란 속성에 의문점을 가지게 되었다.

 

<jsp:include page="b.jsp" flush="true"/>
<jsp:include page="b.jsp" flush="false"/>

대체 이 true와 false는 무엇을 의미하는것일까?  이를 알아보기위해 검색해보았다. 

 

 

 

- flush 속성은 포함될 페이지로 제어가 이동될 때 현재 포함하는 페이지가 지금까지 출력 버퍼에 저장한 결과를 처리하는 방법을 결정한다.

 

- flush 속성의 값을 'true' 로 지정하면 포함될 페이지로 제어가 이동될 때 현재 페이지가 지금까지 버퍼에 저장한 내용을 웹 브라우저에 출력하고 버퍼를 비운다.

 

flush 속성을 일반적으로 'false' 로 지정하는 것이 좋다. 'true'로 지정하면 일단 출력 버퍼를 웹브라우저에 전송하게 되는데 이때 헤더 정보도 같이 전송된다. 헤더 정보가 일단 웹 브라우저에 전송이 되고 나면 헤더 정보를 추가해도 결과가 반영되지 않는다



출처: https://hyeonstorage.tistory.com/94 [개발이 하고 싶어요]

 

[JSP] include 액션 태그

include 액션 태그 - include 액션 태그는 include 디렉티브(<%@include>) 와 함께 다른 페이지를 현재 페이지에 포함시킬 수 있는 기능을 가지고 있다. - include 디렉티브는 단순하게 소스의 내용이 텍스트��

hyeonstorage.tistory.com

 

설명을 보면 아래와 같은데 헤더 정보가 추가해도 결과가 반영되지 않는다는것은 알겠는데 출력 버퍼란 무엇이며

왜 그런일이 발생하는지 의문이 생긴다.

 

 

일단 JSP 출력 버퍼에 대해 설명을 확인하고 가자

 

 

 

 

 

JSP 출력 버퍼(Buffer)

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

JSP는 기본적으로 페이지 처리결과를 곧바로 클라이언트로 출력하여 응답하지 않고, 출력 버퍼에 모아두었다가 한꺼번에 응답 합니다.

 

 

 

 

버퍼 사용시 장점

굳이 곧바로 출력하지 않고 버퍼에 모아두었다가 처리하는 이유는 다음과 같은 장점들이 있기 때문입니다.

 

성능 향상

버퍼에 처리 결과를 모아두었다가 한꺼번에 출력하게 되면 출력 성능이 향상되는데, 처리 결과를 그때그때 조금씩 출력하게 되면 출력 한번한번에 소모되는 비용이 여러번에 반복돼 소모되기 때문에 불필요한 동작들이 발생하게 되는데, 모아두었다가 큰 덩어리로 한번에 출력하게 되면 출력에 관련된 비용을 한번만 사용하면 되는 장점이 있습니다.

 

최종 출력 이전에 처리 결과 수정 가능

버퍼를 사용하지 않고 데이터를 바로 출력해 버리면 엎질러진 물처럼? 중간에 출력 내용을 수정할 수 없습니다.

JSP가 처리된 결과는 결국 최종적으로는 HTTP 응답 메시지입니다. 응답 메시지에는 응답 헤더와 응답 본문이 있는데 out 객체나 표현식을 통해 곧바로 출력되버린 결과는 서버를 떠나버렸기 때문에 헤더와 본문등을 수정하고 싶어도 수정이 불가능합니다.

그러나 버퍼를 이용하면 버퍼에 모아두는 중간에 HTTP 응답 헤더등의 수정이 가능해 지는 장점이 있습니다.

 

<jsp:forward> 기능이나 에러 처리에 용이

만약 a.jsp 라는 페이지가 존재하고 보통의 경우에는 a.jsp에서 모든 처리를 다 하지만 특정 조건의 경우에는 b.jsp로 포워딩(forwarding) 해야 하는 경우가 생기면 어떻게 해야할까요? 버퍼가 없는 경우에는 a.jsp에서 일부 처리결과를 클라이언트로 전송해버린 상태에서 b.jsp로 제어가 넘어가서 b.jsp에서 처리된 결과또한 섞여서 출력될 것입니다.

 

그러나 버퍼를 이용하면 a.jsp의 처리 결과를 출력하던 도중에 특정 조건에서 b.jsp로 포워딩 될 때 출력 버퍼를 비워버리고 제어가 넘어간 b.jsp에서 처리된 결과를 클라이언트로 출력하면 됩니다.

 

 

출처: https://dololak.tistory.com/151 [코끼리를 냉장고에 넣는 방법]

 

[서블릿/JSP] JSP 출력 버퍼란

JSP 출력 버퍼(Buffer) JSP는 기본적으로 페이지 처리결과를 곧바로 클라이언트로 출력하여 응답하지 않고, 출력 버퍼에 모아두었다가 한꺼번에 응답 합니다. 버퍼 사용시 장점 굳이 곧바로 출력하�

dololak.tistory.com

 

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

 

위의 출력버퍼 설명과 flush의 설명을 비교하여 flush 를 생각해보면

 

flush = true 로 설정하는 순간 <jsp:include page="b.jsp" flush="true"/> 속성이 읽히면서

그전에 가지고 있던 버퍼에 담긴 정보를 response 헤더에 쌓아두고 있다가 출력이 되서

이미 출력된 reponse에 대한 헤더를 변경할 수 없다는 것으로 이해했다. 

 

 

 

 

 

이를 설명하기 위해 코드를 구현했는데

a.jsp

<%@page import="java.util.Enumeration"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page buffer="8kb" autoFlush="false" %>

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
----------------------------------------------------page a
<br>
Header 설정-- response.setHeader("a", "1"); 
<%response.setHeader("a", "1"); %>
<br>
session 설정 -- session.setAttribute('1', "1")
<%session.setAttribute("1", "1"); %>
<br>
cookie 설정 -- response.addCookie(new Cookie("co1","1111"));
<%response.addCookie(new Cookie("co1","1111"));%>
<br>
Response Header 출력 -- <% out.write(response.getHeaderNames().toString()); %>
<br>
Response Cookie 출력 -- <% out.write(response.getHeaders("Set-Cookie").toString()); %>
<br>
Request Header 출력 --
<%
Enumeration<String> em = request.getHeaderNames();
while(em.hasMoreElements()) {
	out.write(em.nextElement().toString()+",");
}
%>
<br>
session 출력 -- <%
Enumeration<String> ems = session.getAttributeNames();
while(ems.hasMoreElements()) {
	out.write(ems.nextElement().toString()+",");
}

%>
<br>
<br>
여기서 플러쉬 
<br>
<jsp:include page="b.jsp" flush="true"/>
<br>
----------------------------------------------------page a+
<br>
Header 추가-- response.setHeader("b", "2"); 
<%response.setHeader("b", "2"); %>
<br>
cookie 추가 -- response.addCookie(new Cookie("co2","2222"));
<%response.addCookie(new Cookie("co2","2222"));%>
<br>
Response Header 출력 -- <% out.write(response.getHeaderNames().toString()); %>
<br>
Response Cookie 출력 -- <% out.write(response.getHeaders("Set-Cookie").toString()); %>
<br>
Request Header 출력 --
<%
Enumeration<String> ems2 = request.getHeaderNames();
while(ems2.hasMoreElements()) {
	out.write(ems2.nextElement().toString()+",");
}
%>
<br>
----------------------------------------------------page a+

</body>
</html>

b.jsp

<%@page import="java.util.Enumeration"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page buffer="8kb" autoFlush="false" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

----------------------------------------------------page b
<br>
Header 설정-- response.setHeader("b", "1"); 
<%response.setHeader("b", "1"); %>
<br>
session 설정 -- session.setAttribute('2', "2")
<%session.setAttribute("2", "2"); %>
<br>
cookie 설정 -- response.addCookie(new Cookie("co3","3333"));
<%response.addCookie(new Cookie("co3","3333"));%>
<br>
Response Header 출력 -- <% out.write(response.getHeaderNames().toString()); %>
<br>
Response Cookie 출력 -- <% out.write(response.getHeaders("Set-Cookie").toString()); %>
<br>
Request Header 출력 --
<%
Enumeration<String> em = request.getHeaderNames();
while(em.hasMoreElements()) {
	out.write(em.nextElement().toString()+",");
}
%>
<br>
<%
Cookie[] cookies = request.getCookies();
for(Cookie c : cookies) {
	System.out.println("cookie id : " + c.getName() + " cookie val : "+c.getValue());
}
%>
<br>
session 출력 -- <%
Enumeration<String> ems = session.getAttributeNames();
while(ems.hasMoreElements()) {
	out.write(ems.nextElement().toString()+",");
}
%>
<br>
----------------------------------------------------page b
</html>

 

여기를 진행하면서 정말 신기한 현상을 발견하였다.

 

 

바로

include에 있는 페이지에서 response.addCookie가 동작안하는 현상인데  

 

 

 

 

알아본 결과 

 

inlcude 된 하위 페이지에서는 response로 header를 바꿀수 없는것 같다.

 

https://docs.oracle.com/javaee/6/api/javax/servlet/RequestDispatcher.html#include%28javax.servlet.ServletRequest,%20javax.servlet.ServletResponse%29

 

RequestDispatcher (Java EE 6 )

javax.servlet Interface RequestDispatcher public interface RequestDispatcher Defines an object that receives requests from the client and sends them to any resource (such as a servlet, HTML file, or JSP file) on the server. The servlet container creates th

docs.oracle.com

이부분을 보면 알 수 있다..............

 

 

그래서 이를 확인하기 위해 a를 위와 같이 다시 코딩하였다.

 

 

flush=true로 한 결과 

 

----------------------------------------------------page a
Header 설정-- response.setHeader("a", "1");
session 설정 -- session.setAttribute('1', "1")
cookie 설정 -- response.addCookie(new Cookie("co1","1111"));
Response Header 출력 -- [a, Set-Cookie]
Response Cookie 출력 -- [co1=1111]
Request Header 출력 -- host,connection,cache-control,upgrade-insecure-requests,user-agent,accept,sec-fetch-site,sec-fetch-mode,sec-fetch-user,sec-fetch-dest,accept-encoding,accept-language,cookie,
session 출력 -- 1,2,

여기서 플러쉬
----------------------------------------------------page b
Header 설정-- response.setHeader("b", "1");
session 설정 -- session.setAttribute('2', "2")
cookie 설정 -- response.addCookie(new Cookie("co3","3333"));
Response Header 출력 -- [a, Set-Cookie, Content-Type, Transfer-Encoding, Date]
Response Cookie 출력 -- [co1=1111]
Request Header 출력 -- host,connection,cache-control,upgrade-insecure-requests,user-agent,accept,sec-fetch-site,sec-fetch-mode,sec-fetch-user,sec-fetch-dest,accept-encoding,accept-language,cookie,

session 출력 -- 1,2,
----------------------------------------------------page b
----------------------------------------------------page a+
Header 추가-- response.setHeader("b", "2");
cookie 추가 -- response.addCookie(new Cookie("co2","2222"));
Response Header 출력 -- [a, Set-Cookie, Content-Type, Transfer-Encoding, Date]
Response Cookie 출력 -- [co1=1111]
Request Header 출력 -- host,connection,cache-control,upgrade-insecure-requests,user-agent,accept,sec-fetch-site,sec-fetch-mode,sec-fetch-user,sec-fetch-dest,accept-encoding,accept-language,cookie,
----------------------------------------------------page a+

 

 

flush=false로 한 결과

 

----------------------------------------------------page a
Header 설정-- response.setHeader("a", "1");
session 설정 -- session.setAttribute('1', "1")
cookie 설정 -- response.addCookie(new Cookie("co1","1111"));
Response Header 출력 -- [a, Set-Cookie]
Response Cookie 출력 -- [co1=1111]
Request Header 출력 -- host,connection,cache-control,upgrade-insecure-requests,user-agent,accept,sec-fetch-site,sec-fetch-mode,sec-fetch-user,sec-fetch-dest,accept-encoding,accept-language,cookie,
session 출력 -- 1,2,

여기서 플러쉬
----------------------------------------------------page b
Header 설정-- response.setHeader("b", "1");
session 설정 -- session.setAttribute('2', "2")
cookie 설정 -- response.addCookie(new Cookie("co3","3333"));
Response Header 출력 -- [a, Set-Cookie]
Response Cookie 출력 -- [co1=1111]
Request Header 출력 -- host,connection,cache-control,upgrade-insecure-requests,user-agent,accept,sec-fetch-site,sec-fetch-mode,sec-fetch-user,sec-fetch-dest,accept-encoding,accept-language,cookie,

session 출력 -- 1,2,
----------------------------------------------------page b
----------------------------------------------------page a+
Header 추가-- response.setHeader("b", "2");
cookie 추가 -- response.addCookie(new Cookie("co2","2222"));
Response Header 출력 -- [a, Set-Cookie, b, Set-Cookie]
Response Cookie 출력 -- [co1=1111, co2=2222]
Request Header 출력 -- host,connection,cache-control,upgrade-insecure-requests,user-agent,accept,sec-fetch-site,sec-fetch-mode,sec-fetch-user,sec-fetch-dest,accept-encoding,accept-language,cookie,
----------------------------------------------------page a+

b.jsp 즉 include 된 jsp에서는 response header 등의 쿠키 설정한게 안먹는걸 확인 할 수 있다

Response Header 출력 -- [a, Set-Cookie, b, Set-Cookie]

 

 

결과 비교

 include page="b.jsp" flush="true" 

첫번째는 include page="b.jsp" flush="true" 를 만나고 난 후에는

Response Header 출력 -- [a, Set-Cookie, Content-Type, Transfer-Encoding, Date] 

 

처럼 response에 있는 데이터들이 출력된 것을 확인 할 수있다.

그래서 header에 쿠키나 헤더를 추가하는 작업을 해주어도 동작안하는것을 확인 할 수 있는데 

 

Header 추가-- response.setHeader("b", "2");
cookie 추가 -- response.addCookie(new Cookie("co2","2222"));
Response Header 출력 -- [a, Set-Cookie, Content-Type, Transfer-Encoding, Date]
Response Cookie 출력 -- [co1=1111]

 

 

 

 include page="b.jsp" flush="false" 

 

include가 되고난 후에도 response헤더가 아직 출력되지 않아서 버퍼에 남아있고

Response Header 출력 -- [a, Set-Cookie, b, Set-Cookie]

그로인해 헤더나 쿠키를 추가한것을 

Header 추가-- response.setHeader("b", "2");
cookie 추가 -- response.addCookie(new Cookie("co2","2222"));
Response Header 출력 -- [a, Set-Cookie, b, Set-Cookie]
Response Cookie 출력 -- [co1=1111, co2=2222]

결과로 확인할 수 있다.

반응형