본문 바로가기

SpringMVC

[인프런 강의 복습]스프링 MVC 1편 - 프론트 컨트롤러 패턴

■ 프론트 컨트롤러

1) 프론트 컨트롤러 도입 전
- 프론트 컨트롤러의 도입 전에는 공통의 기능이 중복으로 호출이 되었으며 각각의 컨트롤러(서블릿을 사용)는 요청 url에 따라 호출되었다.

2) 프론트 컨트롤러 도입 후
- 프론트 컨트롤러 서블릿 하나로 클라이언트의 요청을 받음
- 프론트 컨트롤러가 요청에 맞는 컨트롤러를 찾아서 호출
- 프론트 컨트롤러에서 공통의 기능을 처리, 컨트롤러는 서블릿을 사용 X

[참고]
- 스프링 웹 MVC의 핵심도 바로 FrontController
- 스프링 웹 MVC의 DispatcherServlet이 FrontController 패턴으로 구현되어 있다.

 

■ 프론터 컨트롤러 구현 -v1


- 컨트롤러 인터페이스를 도입, 각 컨트롤러는 이 인터페이스를 구현
- 프론트 컨트롤러 서블릿은 이 인터페이스를 호출해서 구현과 관계없이 로직의 일관성을 가져갈 수 있다

- requestURI를 조회해서 실제 호출할 컨트롤러를 controllerMap에서 찾는다.
- 호출된 컨트롤러가 없을 경우, 404 상태 코드를 반환
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);
    }
}
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 {

    private 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);
    }
}
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 {

    private MemberRepository memberRepository = MemberRepository.getInstance();

    @Override
    public void process(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        List<Member> members = memberRepository.findAll();

        //Model에 데이터 보관한다.
        request.setAttribute("members", members);

        String viewPath = "/WEB-INF/views/members.jsp";
        RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
        dispatcher.forward(request, response);
    }
}
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<>();

    //설정정보, servlet이 생성될 때 Map이 생성
    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);   //404 에러를 호출
            return;
        }
        
        controller.process(request, response);
    }
}

 

[출처 : 인프런 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술]