RequestDispatcher

Elenaljh·2023년 8월 8일
1

토막지식

목록 보기
5/5

출처: https://dololak.tistory.com/502
위 블로그의 내용을 정리했습니다!!

RequestDispatcher란

  • 클라이언트로부터 최초에 들어온 요청을 JSP/Servlet 내에서 원하는 자원으로 요청을 넘기는(보내는) 역할을 수행하거나, 특정 자원에 처리를 요청하고 처리 결과를 얻어오는 기능을 수행하는 클래스
  • 요청을 보내는 2가지 방법
    • forward()
    • include()

sendRedirect()와 비교

각 메서드의 소속

  • HttpServletResponse -> sendRedirect()
  • RequestDispatcher -> forward(), include()

sendRedirect()

  • 지정한 경로로 제어를 이동시킬 수 있다.
  • HTTP 리다이렉션을 이용하기 때문에 브라우저에게 이동하려는 경로를 담은 메시지를 response하고, 해당 경로가 담긴 메시지를 다시 request받기 때문에 2번의 HTTP 트랜잭션이 발생한다.
  • 또한 서버측에서는 최초에 받은 요청중에 처리한 내용을 리다이렉트 된 요청 안에서 공유할 수 없다.
    • 대안: 쿠키, 세션 등을 이용해 특정 상태를 유지하는 방식으로 공유할 수 있으나 좋은 방법은 아님
  • forward()와 비교해서 좋은 점: 리다이렉트하면 현재 어플리케이션 이외의 다른 자원의 경로를 요청할 수 있으나, RequestDispatcher은 현재 처리중인 서블릿이 속해있는 웹 어플리케이션 범위 내에서만 요청을 제어할 수 있다.

forward()

  • 브라우저로 다시 요청하는 일 없이 서버 안에서 원하는 목적지로 이동함 (ex. a.jspb.jsp)

RequestDispatcher 생성 방법

1. ServletRequest를 통해 얻는 방법

  • 서블릿 클래스의 service(), doGet(), doPost()
    • 위 메서드들은 HttpServletRequest(ServletRequest의 하위 클래스)를 매개변수로 받기 때문에 이것을 이용해 RequestDispatcher을 얻을 수 있다.
  • 방법: URL 경로를 통해 호출 대상 지정
    • HttpServletRequest는 url이용하는 한가지 방법만을 지원
    • 절대경로, 상대경로 모두 지정 가능
  • 코드: RequestDispatcher dispatcher = request.getRequestDispatcher("URL");

참고
스프링 로드맵 인강에서는 service()메서드를 사용했기 때문에 바로

RequestDispatcher dispatcher = request.getRequestDispatcher("URL");

위 코드 한줄로 RequestDispatcher을 얻을 수 있었다.

2. ServletContext를 통해 얻는 방법

ServletContexts는 서블릿 이름, url 경로(절대경로만)를 이용해 호출대상을 지정할 수 있게 한다.

  • web.xml에 지정한 서블릿 이름으로 호출대상 지정
    ServletContext context = this.getServletContext();
    RequestDispatcher dispatcher = context.getNamedDispatcher("helloServlet");
  • url 경로로 호출대상 지정 (절대경로만 지정 가능)
    ServletContext context = this.getServletContext();
    RequestDispatcher dispatcher = context.getRequestDispatcher("/hello");

RequestDispatcher.forward()

  • 대상 자원으로 제어를 넘기는 역할을 한다.
    • 브라우저에서 /a.jsp를 요청
    • 서버에서는 /a.jspforward()를 실행하여 /b.jsp로 제어를 넘김
    • 브라우저에 /b.jsp의 처리 결과를 응답
  • HTTP 리다이렉트와 달리 하나의 HTTP Request 범위 안에서 동작이 이뤄짐

대상 자원

  • forward()가 제어를 넘기는 대상 자원은 Servlet 또는 JSP 페이지다.
    • (JSP도 최종적으로는 서블릿이다)

forward() 메서드 실습

설명

  • /dispatch로 요청이 넘어오면 DispatchTest 서블릿에서 요청을 처리
    • HttpServletRequest의 저장소에 {"name":"gamza"} 데이터 넘김
      • forward()는 제어가 넘어간 이후 다시 이전의 자원으로 제어가 돌아가지 않으므로 호출하는쪽의 처리를 모두 완료한 후 제어를 넘겨야 함
    • forward()를 통해 /hello로 제어 넘김
      • forward()실행시 HttpServletRequest, HttpServletResponse 객체를 넘겨줌
      • DispatchTest와 HelloServlet은 위의 두 객체를 공유함
  • /hello로 제어가 넘어오면 다음 작업을 처리
    • HttpServletRequest의 저장소에 저장되어 넘어온 값 {"name":"gamza"}를 웹 화면에 출력

코드

  1. /dispatch: dispatchTest 서블릿
@WebServlet(name = "dispatchTest", urlPattern = "/dispatch")
public class DispatchTest extends HttpServlet {
	@Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	request.setCharacterEncoding("UTF-8");
        request.setAttribute("name", "gamza");
        
        RequestDispatcher dispatcher = request.getRequestDispatcher("/hello");
        dispatcher.forward(request, response); 
    }
}
  1. /hello: helloServlet 서블릿
@WebServlet(name = "helloServlet", urlPattern = "/hello")
public class HelloServlet extends HttpServlet {
	@Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	response.setContentType("text/html; charset=utf-8");
        
        Printwriter w = response.getWriter();
        w.println("<HTML>");
        w.println("<head><title>HELLO</title></head>");
        w.println("<body>");
        w.println(""HELLO " + request.getAttribute("name"));
        w.println("</body>");
        w.println("</html>");
    }
}

forward() 사용시 주의할 점

  • forward()는 제어를 넘기기 전에 출력 버퍼를 비운다
    • a.jspb.jsp로 호출시 a.jsp에서 어떤 내용을 버퍼에 출력했더라도 무시됨
    • 제어가 넘어간b.jsp의 출력 내용만 브라우저에 전달된다.

RequestDispatcher.include()

참고: https://dololak.tistory.com/506

0개의 댓글