과정을 즐기자

MVC 프레임워크 구현하기 - 1 본문

Spring

MVC 프레임워크 구현하기 - 1

320Hwany 2022. 10. 29. 16:42

프론트 컨트롤러는 입구를 하나로 만들어 공통적인 처리를 먼저해준다. 프론트 컨트롤러 서블릿 하나로 클라이언트의 요청을 받고 요청에 맞는 컨트롤러를 프론트 컨트롤러가 찾아서 호출한다.

스프링 웹 MVC의 핵심은 프론트 컨트롤러이고 DispatcherServlet으로 구현되어 있다.

 

  • Front Controller V1

먼저 가장 간단한 구조로 확인해보자

프론트 컨트롤러는 서블릿을 사용하였고 ControllerV1 interface를 만들어 나머지 컨트롤러들은 이 인터페이스를 구현한다.

프론트 컨트롤러에서는 먼저 URL 매핑 정보에서 컨트롤러를 조회한다. 

@WebServlet(name = "frontControllerServletV1", urlPatterns = "/front-controller/v1/*")

 

/front-controller/v1 으로 시작하는 URL요청들은 모두 이 프론트 컨트롤러를 호출한다. 프론트 컨트롤러에서는 Map<string, ControllerV1>을 이용하여 각 URL에 맞는 컨트롤러를 반환할 수 있다. 

@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    String requestURI = request.getRequestURI();
    
    ControllerV1 controller = controllerMap.get(requestURI);
    if (controller == null) {
        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    controller.process(request, response);
}

 

다음과 같이 URL요청에 대한 컨트롤러를 호출하고 그 컨트롤러의 process 메소드를 실행한다.

process 메소드는 구현마다 다르지만 공통적으로 JSP를 forward한다. 

String viewPath = "/WEB-INF/views/members.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);

 

이러한 과정을 거쳐 HTML 응답을 할 수 있다.

 

참고로 이때는 model에 데이터를 저장하고 가져오는 과정은 request 객체를 이용하였다.

String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
request.setAttribute("member", member);

 

  • Front Controller V2
String viewPath = "/WEB-INF/views/members.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);

다음으로 중복이 많은 이 부분을 줄이기 위해 View를 분리해보자

컨트롤러에서 바로 JSP forward를 하지 않고 MyView를 프론트 컨트롤러에 반환하고 MyView에서 render 메소드를 호출하며 JSP를 forward하는 방식으로 바꿔보자

 

MyView를 String viewPath를 가진 클래스로 만들고 render 메소드를 만든다. 위에서 중복이 되었던 코드를 render로 구현하였다.

public void render(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
    dispatcher.forward(request, response);
}

 

이제 각 컨트롤러는 MyView 각 객체를 생성하여 반환하면 된다. 다음과 같이 중복이 된 부분을 줄일 수 있다.

@Override
public MyView process(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    return new MyView("/WEB-INF/views/new-form.jsp");
}

'Spring' 카테고리의 다른 글

스프링을 사용하는 이유  (0) 2022.11.17
MVC 프레임워크 구현하기 - 2  (0) 2022.10.29
싱글톤 컨테이너 (모각소 4주차)  (0) 2022.07.24
웹 MVC  (0) 2022.07.18
스프링 빈과 의존관계  (0) 2022.07.18