이전글


RequestDispatcher의 include() 메서드
RequestDispatcher의 메서드 중 하나인 include() 메서드는 처리 흐름 제어를 특정 대상에게 넘기고 대상이 처리한 결과를 현재 페이지에서 처리한 결과에 포함시키는 기능을 합니다. 

include() 메서드의 선언부를 보면 다음과 같이 매개변수로 ServletRequest 객체와 ServletResponse 객체를 넘기는 것을 알 수 있습니다. 우리가 작성하는 서블릿 또는 JSP 페이지에는 이 둘을 상속받은 HttpServletRequest와 HttpServletResponse를 사용하므로 이 둘을 include() 메서드 호출시에 넘겨주면 됩니다.
public void include(ServletRequest request,  ServletResponse response) throws ServletException, IOException; 
cs

 


RequestDispatcher에 대해 자세히 알고 싶으신 분은 상단의 이전글 링크를 참고해 주시기 바랍니다.







forward()와의 동작 방식
이전글에서 forward() 메서드를 알아보았는데, forward() 메서드와는 달리 include() 메서드는 제어를 넘긴 대상페이지의 처리가 완료된 이후 결과와 함께 원래 페이지로 제어가 되돌아오고 이후 나머지 처리를 하게됩니다. 즉 forward() 메서드는 포워딩된 대상 페이지가 최종 결과를 출력했다면 include() 메서드는 최초 흐름이 시작된 페이지(a.jsp)가 브라우저로 최종 결과를 출력합니다.




include() 호출시에는 HttpServletRequest와 HttpServletResponse를 매개변수로 넘겨주는데 이 두 개의 객체를 호출하는 페이지와 호출받는쪽에서 공유하기 때문에 서로 데이터를 이 두 개의 객체에 담아 공유할 수 있습니다. 



또한 브라우저로 데이터를 출력하는 출력스트림(PrintWriter out 객체) 도 하나의 객체를 공유하므로 출력 결과를 포함시키는것처럼 보이게 됩니다. forward()메서드에서는 제어를 호출하는 페이지로 넘기기 전에 출력버퍼의 내용을 비워버리고 제어를 넘기지만 include()는 출력버퍼를 비우지 않기때문에 호출하는 페이지에서 출력하는 내용에 이어서 호출되는 페이지에서 출력하는 내용까지 포함시킬 수 있습니다.





RequestDispatcher 생성(얻는) 방법
RequestDispatcher는 ServletContext나 ServletRequest 클래스에서 제공하는 팩토리 메서드(Factory Method)를 통해 얻을 수 있습니다. 팩토리 메서드라는 용어에 대해서는 이 글의 범위 밖이므로 디자인 패턴을 참고해 주시기 바랍니다. 

ServletContext을 통해서 얻는 법
서블릿 클래스에서 ServletContext를 사용하여 RequestDispatcher를 얻을 수 있습니다.

호출 대상을 web.xml에 지정한 서블릿 이름(<servlet-name>)으로 지정하는 방법
ServletContext context = this.getServletContext(); 
RequestDispatcher dispatcher = context.getNamedDispatcher("helloServlet");                     
cs

호출 대상을 URL 경로로 지정하는 방법. 웹어플리케이션 루트경로를 기준으로 절대경로만 지정할 수 있습니다.
ServletContext context = this.getServletContext(); 
RequestDispatcher dispatcher = context.getRequestDispatcher("/hello");                         
cs

JSP 페이지에서는 application 기본객체를 이용합니다.
<%
     RequestDispatcher dispatcher = application.getRequestDispatcher("/hello");             
%>
cs

 



ServletRequest를 통해서 얻는 법
서블릿 클래스에서는 service() 메서드나 doGet() doPost() 등에서 ServletRequest의 하위 클래스인 HttpServletRequest를 매개변수로 받기 때문에 이것을 이용하여 RequestDispatcher를 얻을 수 있습니다. HttpServletRequest에서는 URL 경로를 통해서 대상을 지정하는 한가지 방법만을 제공합니다. 그러나 ServletContext를 통해서 대상을 지정할때와는 다르게 절대경로 및 상대경로 모두 지정이 가능합니다. JSP 페이지에서도 ServletRequest의 인스턴스인 request 기본객체가 있으므로 스크립트릿 내부에서 동일한 방법으로 얻을 수 있습니다.
RequestDispatcher dispatcher = request.getRequestDispatcher("/hello");                         
cs






RequestDispatcher의 include() 사용하기
서블릿을 기준으로 다음과 같이 DispatchTest(/dispatch) -> HelloServlet(/hello) 로 include()를 실행하는 실습을 해보겠습니다.





DispatchTest(/dispatch) 서블릿 작성
package com.dololak.servlet; 
 
 
import java.io.IOException; 
import java.io.PrintWriter; 
import javax.servlet.RequestDispatcher; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse;

 

 
public class DispatchTest extends HttpServlet { 
     
     @Override 
     protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
          request.setAttribute("name""doloak"); //사전처리 
          
          PrintWriter out = response.getWriter(); 
          System.out.println(out); //콘솔로그출력 
          
          RequestDispatcher dispatcher = request.getRequestDispatcher("/hello"); 
          dispatcher.include(request, response); 
          
          out.println("<!-- HTML 작성자 : dololak -->"); //후처리 
          out.println("</body>"); 
          out.println("</html>");
 
     }
}
 
cs



HelloServlet(/hello) 서블릿 작성
package com.dololak.servlet; 
 
 
import java.io.IOException; 
import java.io.PrintWriter; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
 
public class HelloServlet extends HttpServlet { 
     @Override 
     protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
          response.setContentType("text/html; charset=utf-8"); 
          
          PrintWriter out = response.getWriter(); 
        out.println("<HTML>"); 
        out.println("<head><title>HELLO</title></head>"); 
        out.println("<body>"); 
        out.println("HELLO " + request.getAttribute("name")); 
       
        System.out.println(out); //콘솔로그출력 
     }
}
cs



web.xml 서블릿 경로 맵핑 설정
<servlet> 
     <servlet-name>dispatchServlet</servlet-name> 
     <servlet-class>com.dololak.servlet.DispatchTest</servlet-class>                         
</servlet> 
<servlet-mapping> 
     <servlet-name>dispatchServlet</servlet-name> 
     <url-pattern>/dispatch</url-pattern> 
</servlet-mapping> 
 
 
<servlet>
     <servlet-name>helloServlet</servlet-name> 
     <servlet-class>com.dololak.servlet.HelloServlet</servlet-class> 
</servlet> 
<servlet-mapping> 
     <servlet-name>helloServlet</servlet-name> 
     <url-pattern>/hello</url-pattern> 
</servlet-mapping>
cs



/dispatch를 호출했을 때의 결과입니다. dispatch 서블릿에서 넘긴 데이터 doloak과 함께 hello 서블릿이 제어를 넘겨받아 HTML을 출력했습니다.



출력된 HTML을 열어보면 제어가 disptch 서블릿으로 다시 돌아온 이후 후처리시에 출력했던 주석도 포함된것을 볼 수 있습니다.



콘솔에는 결과 출력시 사용된 PrintWriter out 객체가 찍혀있는 것을 볼 수 있는데 dispatch에서 사용한 out객체과 hello에서 사용한 out객체가 동일한 객체임을 알 수 있고 이것으로 out 객체또한 공유된다는 사실을 알 수 있습니다.



최초 페이지와 include된 페이지의 출력 결과 순서가 맞지 않는경우
만약 최초 페이지와 include 되는 대상 페이지와의 출력 결과에 순서가 맞지 않는다면 제어가 넘어가기 전 출력버퍼를 flush() 해주는것이 좋습니다.
PrintWriter out = response.getWriter(); 
out.println("<HTML>"); 
out.println("<head><title>HELLO</title></head>"); 
 
 
out.flush(); //출력버퍼를 flush()하여 한번 출력 후 제어를 넘김 
 
 
RequestDispatcher dispatcher = request.getRequestDispatcher("/hello");                         
dispatcher.include(request, response); 
cs

 

 

JSP 페이지에서 사용시
JSP도 결국은 서블릿으로 변환되므로 전혀 다를게 없으며, 스크립트릿 내부에서 기본객체(application 또는 request)들을 이용하면 됩니다.
<%
    RequestDispatcher dispatcher = application.getRequestDispatcher("/includee.jsp");        
    dispatcher.include(request, response);
%>
cs

 

 

 


참고글
블로그 이미지

도로락

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

,