“같은 요청을 들고 JSP로 넘긴다”
MVC에서 Controller(서블릿)는 보통 두 가지 중 하나를 선택한다.
- View(JSP)로 화면을 만들어서 응답한다
- 다른 URL로 이동시키도록 응답한다(redirect)
이 글에서는 먼저 MVC에서 가장 기본이 되는 방식인 forward부터 정리한다.
RequestDispatcher는 “요청을 다른 자원에게 넘기는 통로”이다
RequestDispatcher는 말 그대로 “배포/전달” 도구이다.
컨트롤러가 처리하던 요청을
JSP 같은 다른 자원에게 넘겨서 최종 응답을 만들게 한다.
컨트롤러 입장에서는 RequestDispatcher를 이렇게 얻는다.
- request.getRequestDispatcher("JSP 경로")
그리고 forward로 넘긴다.
- dispatcher.forward(request, response)
forward의 가장 중요한 특징: request/response가 그대로 유지된다
forward를 이해할 때 핵심은 이 한 줄이다.
forward는 같은 request/response를 들고 내부에서 이동한다
즉 브라우저는 forward가 일어난 걸 모른다.
- 브라우저가 새 요청을 보내는 게 아니다
- 서버 내부에서 “처리 담당자”만 바뀌는 것이다
그래서 다음이 성립한다.
- 컨트롤러가 request.setAttribute()로 담아둔 값이 JSP에서 그대로 보인다
- request scope가 유지된다
- 주소창(URL)은 바뀌지 않는다
// ================================
// [forward 예시] Controller -> JSP로 "같은 요청"을 넘긴다
// - request.setAttribute로 모델을 담고
// - RequestDispatcher.forward로 JSP에게 요청 처리를 넘긴다
// ================================
@WebServlet("/user/profile")
public class ProfileController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 1) 컨트롤러가 데이터(모델)를 준비한다
String userName = "woojoo";
int point = 1200;
// 2) requestScope에 담는다 (forward로 넘어가면 JSP에서도 그대로 보인다)
req.setAttribute("userName", userName);
req.setAttribute("point", point);
// 3) forward: 같은 request/response를 들고 JSP로 이동
req.getRequestDispatcher("/WEB-INF/views/user/profile.jsp")
.forward(req, resp);
}
}
<!-- /WEB-INF/views/user/profile.jsp -->
<h1>Profile</h1>
<p>name = ${userName}</p>
<p>point = ${point}</p>
위 예제 코드에서 userName, point를 request에 담았기 때문에
JSP는 ${userName}, ${point}로 바로 출력할 수 있다.
forward는 왜 MVC에서 기본이 되는가
forward는 “화면 렌더링”에 최적화된 방식이다.
컨트롤러가 하는 일은 단순해진다.
- 요청 파라미터 처리/검증
- 서비스/DAO 호출
- 화면에 필요한 데이터 준비
- request에 담기(setAttribute)
- JSP로 forward
그리고 JSP는 화면 출력만 담당한다.
즉 역할 분리가 깔끔해진다.
forward vs include (거의 안 쓰는 이유까지)
RequestDispatcher에는 include()도 있다.
- forward() : 지금까지 만든 응답을 무시하고 JSP 결과로 응답을 만든다
- include() : 지금까지 만든 응답 + JSP 결과를 합쳐서 응답한다
실무에서는 대부분 forward만 쓴다.
include는 부분 화면 조합 같은 특수한 상황에서만 쓰는 편이다.
forward의 주의점: 응답을 이미 커밋하면 못 한다
forward는 “JSP가 최종 응답을 만들게 넘기는 것”이다.
그래서 컨트롤러가 response에 이미 많은 내용을 써버리면 문제가 된다.
즉 컨트롤러에서
- response.getWriter()로 바디를 써버리거나
- 이미 응답이 커밋된 상태
라면 forward가 실패할 수 있다.
MVC에서는 그래서 컨트롤러가 response 바디를 직접 쓰는 일을 최소화한다.
핵심 정리
- RequestDispatcher는 요청을 다른 자원(JSP 등)에게 넘기는 도구이다
- forward는 서버 내부 이동이며 같은 request/response가 유지된다
- request scope가 유지되므로 setAttribute로 전달한 데이터가 JSP에서 그대로 보인다
- 주소창 URL은 바뀌지 않는다
- MVC에서 화면 렌더링은 forward가 기본이다
'Web > Web Basics' 카테고리의 다른 글
| [MVC와 웹 흐름 제어] 5. forward vs redirect: 언제 무엇을 써야 하는가 (0) | 2026.03.29 |
|---|---|
| [MVC와 웹 흐름 제어] 4. redirect(sendRedirect) (0) | 2026.03.29 |
| [MVC와 웹 흐름 제어] 1.JSP 단독 사용의 한계: 왜 Controller가 필요해지는가 (0) | 2026.03.29 |
| [서블릿과 JSP] 8. 톰캣(서블릿 컨테이너)은 실제로 무슨 일을 하는가 (0) | 2026.03.29 |
| [서블릿과 JSP] 7. JSTL은 왜 필요하고, <c:forEach>는 무엇인가 (0) | 2026.03.29 |