[Servlet] RequestDispatcher란?

artp·2025년 5월 15일
0

web

목록 보기
6/9
post-thumbnail

RequestDispatcher는 하나의 HTTP 요청을 서버 내부에서 다른 JSP나 서블릿으로 넘기거나, 특정 리소스의 결과를 응답에 포함시킬 수 있게 해주는 서블릿 API의 인터페이스입니다.

즉, 클라이언트가 보낸 하나의 요청을 서버 내부의 다른 자원(JSP, 서블릿 등)으로 넘기거나 포함시킬 수 있도록 도와주는 도구입니다.
이때 이동은 오직 서버 내부에서만 이루어지며, 클라이언트는 이를 인지하지 못합니다.

Dispatcher의 위치와 생성 방식

위치

  • javax.servlet.RequestDispatcher
  • Servlet API에 포함된 표준 인터페이스

생성 방식

RequestDispatcher는 단순한 객체가 아니라, WAS 내부의 요청 제어 시스템(경로 매핑, 버퍼 제어, 요청 전달 등 핵심 로직)과 밀접하게 연결된 객체입니다.

따라서 RequestDispatcher직접 new로 생성하지 않고, WAS에게 요청해서 Dispatcher를 “얻는” 구조로 설계되어 있습니다.

Dispatcher를 얻는 두 가지 방식

RequestDispatcher는 개발자가 직접 생성하지 않고, 다음 두 객체를 통해 얻습니다.

  • HttpServletRequest 객체 - request.getRequestDispatcher()
  • ServletContext 객체 - getServletContext().getRequestDispatcher() 또는
    context.getRequestDispatcher()
방식설명코드
HttpServletRequest 객체현재 서블릿의 경로 기준 상대경로로 Dispatcher를 가져옴request.getRequestDispatcher("result.jsp")
ServletContext 객체애플리케이션 루트(/) 기준 절대 경로로 Dispatcher를 가져옴getServletContext().getRequestDispatcher("/WEB-INF/result.jsp")

두 방식의 차이

구분기준 경로사용 예시특징
request.getRequestDispatcher()현재 요청한 서블릿의 위치 기준 상대 경로"result.jsp"상대 경로라서 경로 실수가 발생할 수 있음
context.getRequestDispatcher()웹 애플리케이션 루트(/) 기준 절대 경로"/WEB-INF/views/result.jsp"구조가 명확하고 실무에서 더 선호됨
  • request 방식은 현재 서블릿 파일이 있는 위치 기준으로 경로를 해석합니다. 경로 계산이 까다로워 실수할 가능성이 있습니다.
  • context 방식은 항상 루트(/) 기준으로 경로를 지정하므로 구조가 명확하고, WEB-INF와 같은 외부 접근 불가 경로에도 접근할 수 있어 실무에서 더 많이 사용됩니다.

RequestDispatcher 사용 이유?

  • 하나의 서블릿이 모든 처리를 담당하지 않도록 역할을 분리할 수 있습니다.
    → 예: 로그인 서블릿은 인증만 처리하고, 결과 화면은 JSP가 담당
  • 클라이언트는 요청을 한 번만 보내지만, 서버 내부에서는 여러 리소스(JSP, 서블릿 등)가 서로 협력하여 응답을 완성할 수 있습니다.
    → 이 과정에서 요청 객체(request)와 응답 객체(response)는 그대로 유지되기 때문에 데이터를 공유하며 응답을 만들 수 있습니다.
  • 요청을 다른 리소스로 “넘기거나(→ forward), 끼워 넣는(→ include)” 방식으로 코드의 재사용성과 구조화된 응답 구성이 가능해집니다.

“요청 한 번에 여러 자원이 응답을 구성한다”는 뜻

예시 시나리오

클라이언트가 로그인 요청:

POST /login

위 요청을 처리할 수 있는 방식에는 다음의 두 가지가 있습니다.

방식설명
response.sendRedirect("/welcome.jsp")클라이언트에게 다시 /welcome.jsp를 요청하라고 지시 (요청이 두 번)
RequestDispatcher.forward("/welcome.jsp")클라이언트 요청을 서버 내부에서 JSP로 넘김 (요청은 한 번만 발생)

실제 동작 차이

sendRedirect 흐름 (2번 요청)

1. 클라이언트 → /login 요청
2. 서버: 로그인 처리 완료 → "응답 헤더에 Location: /welcome.jsp"
3. 클라이언트가 다시 → /welcome.jsp 요청
4. 서버 → welcome.jsp를 실행하고 응답
  • 요청이 두 번 발생
  • 클라이언트와 서버 간의 연결도 두 번 열림
  • 첫 번째 요청에서 만든 request 속성은 두 번째 요청에서 사라짐
  • 클라이언트가 URL 바뀐 걸 감지할 수 있음

forward 흐름 (1번 요청)

1. 클라이언트 → /login 요청
2. 서버: 로그인 처리 완료 → 내부에서 "/welcome.jsp"로 forward
3. 서버가 JSP 실행 → 바로 클라이언트에게 응답
  • 요청은 한 번
  • request와 response 객체가 계속 유지
  • 서버 내부에서 연결과 자원 전달이 빠르게 진행
  • 클라이언트 입장에선 처리 흐름이 한 번이고, URL도 안 바뀜

즉, “요청 한 번으로 여러 자원이 협력해 응답을 구성한다”는 건, 클라이언트 입장에서는 한 번 요청했을 뿐인데,
서버 내부에서 서블릿 → JSP로 데이터와 흐름이 자연스럽게 전달되어 결과적으로 응답이 깔끔하고 구조적인 방식으로 완성된다는 뜻입니다.

RequestDispatcher의 두 가지 핵심 기능

메서드설명사용 예시
forward()요청을 다른 서블릿/JSP로 넘김. 사용자는 이동 사실을 모름.로그인 처리 → 결과 JSP
include()다른 결과를 현재 응답 중간에 끼워 넣음. 응답 내용이 합쳐짐.헤더/푸터 공통 삽입 등
  • forward(): 제어 흐름 자체를 넘깁니다. 기존 응답 버퍼는 비워지고, 새 리소스의 결과만 전송됩니다.
  • include(): 현재 응답 스트림에 다른 리소스의 결과를 "포함"합니다. include 전후의 출력이 모두 응답에 포함됩니다.

forward()의 동작 방식

  • 클라이언트는 한 번만 요청합니다. (내부 이동)
  • 서버 내부에서만 다른 JSP/서블릿으로 요청이 이동합니다.
  • 클라이언트의 URL은 변하지 않습니다.
  • 기존 응답 내용은 지워지고, 포워드된 결과만 전송됩니다.
RequestDispatcher rd = request.getRequestDispatcher("result.jsp");
rd.forward(request, response);

include()의 동작 방식

  • 현재 응답 중간에 다른 결과를 삽입합니다.
  • 응답 내용이 합쳐집니다.
  • 주로 공통 요소(헤더, 메뉴, 푸터 등) 삽입에 사용합니다.
RequestDispatcher rd = request.getRequestDispatcher("header.jsp");
rd.include(request, response);

주의

  • forward() 이후에는 절대 response.getWriter() 등으로 출력하면 안 됩니다.
    → 응답 버퍼가 이미 비워지고, 제어권이 포워드된 리소스로 완전히 넘어갔기 때문입니다.
  • forward()는 외부 URL로 이동할 수 없습니다.
    → 서버 내부 리소스(JSP, 서블릿 등)만 가능합니다.
  • include()는 include 전/후의 출력 모두가 최종 응답에 포함됩니다.

정리

RequestDispatcher는 서버 내부에서 요청을 다른 리소스로 “넘기거나 끼워 넣을 수 있게 해주는 도구”입니다.

  • forward() → 요청을 다른 곳으로 넘김 (응답을 완전히 대체)
  • include() → 다른 리소스의 결과를 현재 응답에 끼워 넣음
  • context.getRequestDispatcher()절대 경로 (루트 기준)
  • request.getRequestDispatcher()상대 경로 (현재 경로 기준)

참고

  • forward()와 include() 모두 하나의 HTTP 요청 안에서만 동작합니다.
  • 클라이언트는 내부 이동을 전혀 알 수 없습니다.
    → 실제로는 요청은 한 번, 응답도 한 번만 전달됩니다.
profile
donggyun_ee

0개의 댓글