현의 개발 블로그

[MVC 프레임워크 만들기] 프론트 컨트롤러 도입 본문

스프링부트 이론/MVC

[MVC 프레임워크 만들기] 프론트 컨트롤러 도입

hyun2371 2023. 6. 23. 20:50

프론트 컨트롤러 소개

프론트 컨트롤러 도입 전

입구가 없다. 각 컨트롤러마다 공통로직이 중복된다.

ex) 뷰로 이동하는 로직

 

프론트 컨트롤러 도입 후

공통 로직을 입구에 몰아넣고, 각 컨트롤러에 필요한 로직은 각자 처리한다.

 

 

frontController 패턴 특징

  • 프론트 컨트롤러 내 서블릿 하나로 클라이언트의 요청을 받는다.
  • 프론트 컨트롤러가 요청에 맞는 컨트롤러를 찾아서 호출해준다.
  • 입구가 하나이기 때문에 공통 처리가 가능하다.
  • 프론트 컨트롤러를 제외한 나머지 컨트롤러는 서블릿을 사용하지 않아도 된다.

 

스프링 웹 MVC와 프론트 컨트롤러

스프링 웹 MVC의 핵심이 바로 Front Controller이다.

스프링 웹 MVC의 DispatcherServlet은 Front Controller 패턴으로 구현되어 있다.

 

 

도입

FrontController는 어떤 컨트롤러를 호출해야 하는지 찾아 호출한다.

컨트롤러가 실행되고, 컨트롤러가 JSP를 포워드 한다.

 

인터페이스 정의

public interface ControllerV1 {
      void process(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException;
  }

서블릿과 유사한 메서드를 가진 컨트롤러 인터페이스를 도입한다.

각 컨트롤러들은 해당 인터페이스를 상속받아 구현한다.

 

프론트 컨트롤러는 컨트롤러에서 구현한 해당 인터페이스를 호출하여 로직의 일관성을 가질 수 있다.

 

 

Controller

위 인터페이스를 구현한 Controller 들을 만든다.

각 controller 로직은 servletmvc 패키지에 있는 controller들과 똑같다.

 

회원 등록

public class MemberListControllerV1 implements ControllerV1{
    @Override
    public void process(HttpServletRequest request, HttpServletResponse
    response) throws ServletException, IOException {
        String viewPath = "/WEB-INF/views/new-form.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);
}

 

로직은 MvcMemberFormServlet.java와 동일하다.

 

dispatcher.forward()

다른 servlet이나 JSP로 이동할 수 있는 기능이다.

servlet을 호출하면, JSP가 호출되고 클라이언트에 응답값을 반환한다.

 

 

 

회원 저장

public class MemberSaveControllerV1 implements ControllerV1 {
   @Override
   public void process(HttpServletRequest request, HTtpSErvletResponse response)
   throws ServletException, IOException {
   
    String username = request.getParameter("username");
    int age = Integer.parseInt(request.getParameter("age"));
    
    Member member = new Member(username, age);
    memberRepository.save(member);
    request.setAttribute("member", member);
    
    String viewPath = "/WEB-INF/views/save-result.jsp";
    RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
    dispatcher.forward(request, response);
   }
}

 

회원 목록

public class MemberListControllerV1 implements ControllerV1 {
    ...
    List<Member> members = memberRepository.findAll();
    request.setAttribute("members", members);

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

 

 

Front Controller

@WebServlet(name = "frontControllerServletV1", urlPatterns= "/front-controller/v1/*")
public class FrontControllerServletV1 extends HttpServlet {
    private Map<String, ControllerV1> controllerMap = new HashMap<>(); //매핑정보

    public FrontController(){
        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());
     }
}

urlPatterns =/front-controller/v1/*

하위에 어떤 url이 들어와도 FrontControllerServletV1이 호출된다.

 

Map에 url과 Controller 객체가 key-value값으로 저장된다.

Map을 통해 어떤 컨트롤러가 호출되어야 하는지 찾는다.

호출된 컨트롤러는 JSP를 포워드 한다.

 

JSP는 이전 MVC에서 사용했던 것을 재사용한다.

 

    @Override 
    void service(HttpServletRequest request, HttpServletResponse response){
    String requestURI = request.getRequestURI();
	
    //ex) MemberFormControllerV1 반환
    ControllerV1 controller = controllerMap.get(requestURI); 
    if (controller == null) {
        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
        return;
    }

    controller.process(request, response); //인터페이스 호출
 }

requestUri에 맞는 컨트롤러 인스턴스 주소값이 반환된다.

만약에 찾는 컨트롤러가 존재하지 않는다면 null이 되고, 404 상태코드를 반환한다.

해당 코드로 다형성이 보장된다.

 

 

 

 

 


Reference

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -

www.inflearn.com

 

Comments