서블릿(Servlet) 구조의 한계와 프론트 컨트롤러가 필요한 이유

신정범·2026년 2월 22일

Spring

목록 보기
3/6

서블릿으로 MVC 구조를 직접 구현하다 보면
코드는 돌아가지만, 구조적으로 계속 찜찜한 지점들이 생긴다.
이번 글에서는 그중에서도 View 이동과 관련된 중복 문제를 중심으로
왜 프론트 컨트롤러가 등장했는지 정리해본다.


  1. 서블릿 MVC에서 발생하는 중복 문제

① View로 이동하는 코드의 중복 (forward 중복)

컨트롤러 역할을 하는 모든 서블릿에서
JSP로 이동할 때마다 아래 코드가 반복된다.

RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);

회원 목록, 회원 저장, 회원 폼 등
모든 서블릿에서 동일한 코드가 계속 등장한다.
• 메서드로 분리할 수는 있음
• 하지만 결국 매번 직접 호출해야 함
• 컨트롤러의 핵심 로직이 아닌 코드가 계속 눈에 띔

-컨트롤러가 비즈니스 흐름 제어에만 집중하지 못한다.-


② View 경로 문자열 중복 (ViewPath 중복)

String viewPath = "/WEB-INF/views/new-form.jsp";

여기에는 두 가지 문제가 숨어 있다.

✔ prefix / suffix가 하드코딩됨
• prefix: /WEB-INF/views/
• suffix: .jsp

모든 컨트롤러에서 이 문자열을 직접 작성해야 한다.

✔ View 기술 변경에 취약
만약 View를 JSP → Thymeleaf로 바꾸면?

// 기존
"/WEB-INF/views/new-form.jsp"

// 변경 후
"/templates/new-form.html"

모든 컨트롤러 코드를 수정해야 함

즉,
• 컨트롤러가 View 기술(JSP, Thymeleaf)에 강하게 결합
• 변경에 매우 취약한 구조


  1. 문제의 본질: 책임이 흩어져 있다

현재 구조에서는
• 요청 분기
• 비즈니스 로직 호출
• View 선택
• forward 처리

이 모든 책임이 각 서블릿마다 흩어져 있음, 컨트롤러가 너무 많은 일을 함.

  1. 해결 아이디어: 공통 로직을 한 곳으로 모으자

여기서 자연스럽게 나오는 질문:

“이 공통 코드를 한 곳에서 처리할 수는 없을까?”

그래서 등장하는 개념이 바로 프론트 컨트롤러(Front Controller) 이다.

  1. 프론트 컨트롤러란?

모든 요청을 단 하나의 컨트롤러가 먼저 받는 구조

클라이언트 요청
      ↓
[Front Controller]
      ↓
각 기능별 컨트롤러
      ↓
View

  1. 프론트 컨트롤러가 해결해주는 것들

    1) forward 로직을 한 곳에서 처리

RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);

이 코드는 프론트 컨트롤러에 단 한 번만 존재한다.
개별 컨트롤러에서는
“어떤 뷰를 쓸지”만 반환하면 된다.


2) ViewPath 조립 책임 분리

개별 컨트롤러:

return "new-form";

프론트 컨트롤러:

String viewPath = "/WEB-INF/views/" + viewName + ".jsp";

prefix / suffix가 한 곳에만 존재
View 기술 변경 시 수정 포인트 단 하나


3) 컨트롤러의 역할이 명확해짐

컨트롤러는 이제 딱 이것만 한다.
• 요청 파라미터 처리
• 비즈니스 로직 호출
• 논리적인 View 이름 반환

Controller = 요청 처리 + 흐름 결정
View 처리 = Front Controller
profile
성장하는 개발자가 되겠습니다

0개의 댓글