-
[김영한 스프링] 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
'Spring > 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술' 카테고리의 다른 글
[김영한 스프링] 15. MVC 프레임워크 만들기 - Model 분리 (0) 2023.06.30 [김영한 스프링] 14. MVC 프레임워크 만들기 - View 분리 (0) 2023.06.29 [김영한 스프링] 12. MVC 패턴 (0) 2023.06.28 [김영한 스프링] 11. JSP로 회원 관리 웹 애플리케이션 만들기 (0) 2023.06.22 [김영한 스프링] 10. 서블릿으로 회원 관리 웹 애플리케이션 만들기, Welcome 페이지 변경 (0) 2023.06.19