Spring

[Spring] MVC 5편 - 프론트 컨트롤러 v1

dev-nadan 2025. 8. 12. 21:15

이번 편에서는 프론트 컨트롤러 패턴을 도입해보며, 스프링 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. 실행 흐름

  1. 사용자가 /front-controller/v1/members/new-form 요청
  2. 프론트 컨트롤러가 해당 URL에 매핑된 MemberFormControllerV1 실행
  3. 컨트롤러가 JSP forward 수행
  4. 결과 화면 렌더링

5. 회고

이 버전을 구현하면서, ‘프론트 컨트롤러가 입구를 하나로 모은다’는 개념이 정말 핵심이라는 걸 느꼈다.

과거 프로젝트에서는 서블릿이 여러 개 흩어져 있었고, 공통 로직을 한 번에 수정하기 힘들었는데, 이렇게 중앙집중식으로 관리하면 유지보수가 훨씬 편해진다.

다만 여전히 컨트롤러마다 forward 코드가 중복되고, HttpServletRequest/Response에 종속적인 구조라는 한계가 보인다.