ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [김영한 스프링] 13. MVC 프레임워크 만들기 - 프론트 컨트롤러 소개&도입
    Spring/스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 2023. 6. 29. 00:26

    프론트 컨트롤러 패턴 소개

     

    프론트 컨트롤러 도입 전

     

     

    프론트 컨트롤러 도입 후

     

     

    FrontController 패턴 특징

    • 프론트 컨트롤러 서블릿 하나로 클라이언트의 요청을 받음
    • 프론트 컨트롤러가 요청에 맞는 컨트롤러를 찾아서 호출
    • 입구를 하나로!
    • 공통 처리 가능
    • 프론트 컨트롤러를 제외한 나머지 컨트롤러는 서블릿을 사용하지 않아도 됨

     

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

    스프링 웹 MVC의 핵심도 바로 FrontController

    스프링 웹 MVC의 DispatcherServlet이 FrontController 패턴으로 구현되어 있음

     

    프론트 컨트롤러 도입 - v1

     

    V1 구조

     

     

    ControllerV1

    package hello.servlet.web.frontcontroller.v1;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public interface ControllerV1 {
    
        void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
    }

    main/java/hello.servlet/web/frontcontroller/v1/ControllerV1 생성

     

    서블릿과 비슷한 모양의 컨트롤러 인터페이스를 도입한다. 각 컨트롤러들은 이 인터페이스를 구현하면 된다. 프론트 컨트롤러는 이 인터페이스를 호출해서 구현과 관계없이 로직의 일관성을 가져갈 수 있다.

     

     

    MemberFormControllerV1 - 회원 등록 컨트롤러

    main/java/hello.servlet/web/frontcontroller/v1/controller/MemberFormControllerV1 생성

     

     

    package hello.servlet.web.frontcontroller.v1.controller;
    
    import hello.servlet.web.frontcontroller.v1.ControllerV1;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class MemberFormControllerV1 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);
        }
    }

     

     

    MemberSaveControllerV1 - 회원 저장 컨트롤러

    main/java/hello.servlet/web/frontcontroller/v1/controller/MemberSaveControllerV1 생성

     

     

    package hello.servlet.web.frontcontroller.v1.controller;
    
    import hello.servlet.domain.member.Member;
    import hello.servlet.domain.member.MemberRepository;
    import hello.servlet.web.frontcontroller.v1.ControllerV1;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class MemberSaveControllerV1 implements ControllerV1 {
    
        MemberRepository memberRepository = MemberRepository.getInstance();
    
        @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);
    
            // Model에 데이터를 보관한다.
            request.setAttribute("member", member);
    
            String viewPath = "/WEB-INF/views/save-result.jsp";
            RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
            dispatcher.forward(request, response);
        }
    }

     

     

    MemberListControllerV1 - 회원 목록 컨트롤러

    main/java/hello.servlet/web/frontcontroller/v1/controller/MemberListControllerV1 생성

     

     

    package hello.servlet.web.frontcontroller.v1.controller;
    
    import hello.servlet.domain.member.Member;
    import hello.servlet.domain.member.MemberRepository;
    import hello.servlet.web.frontcontroller.v1.ControllerV1;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.List;
    
    public class MemberListControllerV1 implements ControllerV1 {
    
        MemberRepository memberRepository = MemberRepository.getInstance();
    
        @Override
        public void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            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);
    
        }
    }

     

     

    MemberListControllerV1 - 회원 목록 컨트롤러

    main/java/hello.servlet/web/frontcontroller/v1/MemberListControllerV1 생성

     

     

     

     

    실행

     

     

    결과

     

     

    package hello.servlet.web.frontcontroller.v1;
    
    import hello.servlet.web.frontcontroller.v1.controller.MemberFormControllerV1;
    import hello.servlet.web.frontcontroller.v1.controller.MemberListControllerV1;
    import hello.servlet.web.frontcontroller.v1.controller.MemberSaveControllerV1;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    
    @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 {
            System.out.println("FrontControllerServletV1.service");
    
            String requestURI = request.getRequestURI(); // 웹에서 입력한 주소를 받음
    
            ControllerV1 controller = controllerMap.get(requestURI);
    
            if (controller == null) {
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
    
            controller.process(request, response);
        }
    }

     

     

    실행

     

     

    uriPatterns

    • urlPatterns = "/front-controller/v1/*" : /front-controller/v1를 포함한 하위 모든 요청은 이 서블릿에서 받아들인다.
    • 예) /front-controller/v1, /front-controller/v1/a, /front-controller/v1/a/b

     

    controllerMap

    • key: 매핑 URL
    • value: 호출될 컨트롤러

     

    service()

    먼저 requestURI를 조회해서 실제 호출할 컨트롤러를 controllerMap에서 찾는다. 만약 없다면 404(SC_NOT_FOUND) 상태 코드를 반환한다.

    컨트롤러를 찾고 controller.process(request, response);을 호출해서 해당 컨트롤러를 실행한다.

     

    JSP

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

     

     

    출처 : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1

     

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

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

    www.inflearn.com

Designed by Tistory.