이번 편에서는 프론트 컨트롤러 패턴을 도입해보며, 스프링 MVC의 핵심 구조가 어떻게 만들어지는지 기초부터 살펴본다.
1. 프론트 컨트롤러란?
- 입구를 하나로: 하나의 서블릿(FrontControllerServlet)이 모든 요청을 받는다.
- 요청을 분석하여 알맞은 컨트롤러를 찾아 호출한다.
- 공통 로직(로그, 인증, 예외처리 등)을 한 곳에서 처리할 수 있다.
- 스프링 MVC의 DispatcherServlet이 이 패턴을 구현하고 있다.
2. V1 구조
- ControllerV1 인터페이스를 만들어 모든 컨트롤러가 이를 구현하도록 한다.
- 각 컨트롤러는 서블릿과 비슷하게 HttpServletRequest, HttpServletResponse를 받아 처리.
- 프론트 컨트롤러는 URL 매핑(controllerMap)으로 어떤 요청이 어떤 컨트롤러로 가야 하는지 결정.
- JSP 뷰 호출까지는 기존과 동일하게 직접 forward 처리.
3. 핵심 코드
@WebServlet(name = "frontControllerServletV1", urlPatterns = "/front-controller/v1/*")
public class FrontControllerServletV1 extends HttpServlet {
private Map<String, ControllerV1> controllerMap = new HashMap<>();
public FrontControllerServletV1() {
controllerMap.put("/front-controller/v1/members/new-form", new MemberFormControllerV1());
controllerMap.put("/front-controller/v1/members/save", new MemberSaveControllerV1());
controllerMap.put("/front-controller/v1/members", new MemberListControllerV1());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ControllerV1 controller = controllerMap.get(request.getRequestURI());
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
controller.process(request, response);
}
}
4. 실행 흐름
- 사용자가 /front-controller/v1/members/new-form 요청
- 프론트 컨트롤러가 해당 URL에 매핑된 MemberFormControllerV1 실행
- 컨트롤러가 JSP forward 수행
- 결과 화면 렌더링
5. 회고
이 버전을 구현하면서, ‘프론트 컨트롤러가 입구를 하나로 모은다’는 개념이 정말 핵심이라는 걸 느꼈다.
과거 프로젝트에서는 서블릿이 여러 개 흩어져 있었고, 공통 로직을 한 번에 수정하기 힘들었는데, 이렇게 중앙집중식으로 관리하면 유지보수가 훨씬 편해진다.
다만 여전히 컨트롤러마다 forward 코드가 중복되고, HttpServletRequest/Response에 종속적인 구조라는 한계가 보인다.
'Spring' 카테고리의 다른 글
[Spring] MVC 7편 - 프론트 컨트롤러 v3 (2) | 2025.08.12 |
---|---|
[Spring] MVC 6편 - 프론트 컨트롤러 v2 (0) | 2025.08.12 |
[Spring 완전 정복 시리즈 - MVC편] 4편 - 서블릿에서 JSP, 그리고 MVC로 (4) | 2025.08.11 |
[Spring 완전 정복 시리즈 - MVC편] 3편 - 서블릿 응답의 모든 것 (3) | 2025.08.07 |
[Spring 완전 정복 시리즈 - MVC편] 2편 - 서블릿의 기본 개념과 동작 원리 (4) | 2025.08.07 |