Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

response.sendRedirect()에 대해서....

JSP로 페이지 작업을 하면서 페이지를 이동하기 위해서 자연스레 response.sendRedirect()를 사용했다. 나름 자바스크립트의 location.href()로 이동하는 것 보다는 나을꺼라는 생각으로 근데 오히려 문제가 많았다. 처음엔 꽤 해맸는데 이런저런 자료를 찾다가 response.sendRedirect()에 대해서 좀 알게 되었다.

response.sendRedirect()는 생긴거는 아주 직관적으로 생겼다.(물론 오해지만...) resonse를 리다이렉트 시켜버린다는 건데 실제 동작은 그렇게 직관적이지 않다. 직관적이지 않다고 말한 이유는 자바스크립트의 location.href()가 해당 코드를 만나는 순간 페이지를 이동하는 반면에 response.sendRedirect()를 실행될때 페이지를 이동하는 것이 아니라 페이지의 Header정보의 HTTP 상태코드(Status code)를 301로 바꾸어서 보내준다. 헤더를 바꾼다는 의미는 response.sendRedirect()이하의 모든 코드를 다 실행한다는 얘기다.


<body>
<% response.sendRedirect("target.jsp"); %>
<% System.out.println("test"); %>
</body>


jsp라는 것을 전제하에 스크립틀릿으로 작성했고 기본적인 html태그는 생략했다. 이 소스를 실행하면 콘솔에 "test"가 찍힐까 안찍힐까... 동작원리를 몰랐을때는 안찍힌다고 생각했는데 이건 찍힌다. response.sendRedirect() 아래의 코드는 실행이 안된다고 생각하기 쉽지만 response.sendRedirect()는 위에 말한대로 헤더의 상태코드만 바꿔주는 역할을 하기 때문에 이하 페이지의 모든 소스가 다 실행된다.즉 아래쪽 코드를 실행하는데 에러가 있다면 response.sendRedirect()이 되지 않고 에러메시지만 나타난다. response.sendRedirect()이하코드를 실행하기 싫다면 if-eles문을 이용해서 아예 다른쪽 코드는 실행자체가 되지 않도록 해야한다.



<body>

<% 
    if (회원이 아니면) {
        response.sendRedirect("target.jsp"); 
    } else {
        // 회원일 땐의 동작 코드
    }
%>

</body>


의미 전달이 중요하지 코드는 중요하지 않기 때문에 if-else구문은 그냥 한글로 처리해버렸다. ^^;;; 어쨌든 저런식으로 else문의 반대쪽 코드를 다 넣어야 한다. 에러가 안나더라도 아래쪽에 시간을 많이 소비하는 소스가 있다면 필요도 없는 소스에 리소스를 낭비하게 되는 겪이다.






그럼 헤더의 상태코드를 받는다는 것은 무엇인가. W3C의 HTTP/1.1 Status Code Definitions을 보면 상태코드에 대해서 자세히 나와있다. 대략적으로 몇가지 적으면

200 OK
301 Moved Permanently
403 Forbidden
404 Non Found
500 Internal Sever Error


등이 있다. 익숙한 코드들이 많이 보인다. 브라우저가 서버측에 페이지를 요청에서 받은 정보의 헤더정보의 상태코드를 봐서 200이면 정상이므로 페이지가 보여지고 403, 404, 500코드이면 에러메시지를 보여준다. 여기서 response.sendRedirect()는 이 상태코드를 301로 바꿔서 보내주고 브라우저는 상태코드가 301이 오면 같이 받은 URL로 다시 요청을 보내는 것이다. 당연히 브라우저는 클라이언트쪽이기 때문에 서버쪽에서는 모든 코드가 다 실행되는 것이다.


이런 response.sendRedirect()의 동작원리 때문에 발생한 문제가 또 있다. include를 사용했을 때의 문제인데 include에는 2가지 방식이 있다. 정적인 방식과 동적인 방식이 있는데

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

와 같이 작성하면 동적인 방식이고 페이지가 요청될때마다 인클루드하는 파일을 새로 읽어온다.

<%@ include file="incl.jsp" %>

위와같이 작성하면 정적으로 인클루드를 컴파일단계에서 해당소스를 인클루드를 하는 파일의 소스에 집어넣는다. (수행속도는 당연히 정직인 방식이 빠르다.)



여기서 동적인 방식으로 인클루드 했을 때 incl.jsp파일에서 response.sendRedirect()를 사용해도 작동을 하지 않는다. 처음에는 혼란스러웠지만 동작원리를 알고다면 그다지 혼란스럽지 않다. 100%확신까진 아니지만 response.sendRedirect()는 incl.jsp의 Header의 상태코드를 변경했고 이 변경된 코드가 브라우져에 전달된것이 아닌 인클루드 해온 파일에 전달되었고 그 파일의 상태코드는 301이 아니기 때문에 리다이렉션 자체가 수행되지 않는다. 당연히 정직인 방식으로 인클루드 했을때문 문제없이 수행된다. (물론 위에 말한대로 그 이하 소스도 다 수행된다.)
2008/08/18 21:55 2008/08/18 21:55