frontcontroller package를 폴더 구조 세팅을 아래와 같이 해주자.
package hello.setvlet.web.frontcontroller.v1;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public interface ControllerV1 {
// Servlet와 같은 인터페이스를 하나 만듬
void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
요청이 왔을 때 매핑 정보에서 호출을 하면 일관성 있게 다형성에 의존하면서 편리하게 호출할 수 있다.
구현 Controller들을 다른 패키지 안에 모아놓자. MeberFormControllerV1를 만들어 주고
MvcMemberFormServlet에 있는 코드를 가져와서 넣어준다.
String viewPath = "/WEB-INF/views/new-form.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
// MemberFormControllerV1 Class
package hello.setvlet.web.frontcontroller.v1.controller;
import hello.setvlet.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도 만들어서 넣어주자. 마찬가지로 Servlet 파일에 있는 코드를 가져와서 붙여놓자.
private MemberRepository memberRepository = MemberRepository.getInstance();
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);
// MemberSaveControllerV1
package hello.setvlet.web.frontcontroller.v1.controller;
import hello.setvlet.domain.member.Member;
import hello.setvlet.domain.member.MemberRepository;
import hello.setvlet.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);
request.setAttribute("member", member);
String viewPath = "/WEB-INF/views/save-result.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
MemberControllerV1도 만들어준다. 마찬가지로 Servlet파일 MvcMemberListServlet 파일에 있는 코드를 가져와서 붙인다.
package hello.setvlet.web.frontcontroller.v1.controller;
import hello.setvlet.domain.member.Member;
import hello.setvlet.domain.member.MemberRepository;
import hello.setvlet.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();
request.setAttribute("members", members);
String viewPath = "/WEB-INF/views/members.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
FrontControllerServletV1도 만들어 주고 돌려주자.
package hello.setvlet.web.frontcontroller.v1;
import hello.setvlet.web.frontcontroller.v1.controller.MemberFormControllerV1;
import hello.setvlet.web.frontcontroller.v1.controller.MemberListControllerV1;
import hello.setvlet.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;
// v1/ 하위에 어떤 url이 들어와도 Servlet은 호출이 된다.
@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 req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("FrontControllerServletV1.service");
}
}
잘 나오는 걸 볼 수 있다.
System.out.println("FrontControllerServletV1.service");
V1 구조 그림을 다시가서 확인하면 매핑정보를 만들고 만든 매핑정보 map을 통해서 어떤 Front Controller가 호출되는지 찾는다.
그리고 Controller가 JSP에게 Forward를 해주고 HTML로 응답을 하게된다.
위 그림과 일치하게 FrontControllerV1을 다시 작성하여 돌려보자.
package hello.setvlet.web.frontcontroller.v1;
import hello.setvlet.web.frontcontroller.v1.controller.MemberFormControllerV1;
import hello.setvlet.web.frontcontroller.v1.controller.MemberListControllerV1;
import hello.setvlet.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;
// v1/ 하위에 어떤 url이 들어와도 Servlet은 호출이 된다.
@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");
// getRequestURI 부분이 그대로 /front-controller/v1/members/new-form 이거랑 같게 된다.
String requestURI = request.getRequestURI();
// 여기서 꺼내주자.
// /front-controller/v1/members/new-form 이게 호출이 되면 MemberFormControllerV1 이게 반환
// /front-controller/v1/members/save 이게 호출이 되면 MemberFormControllerV1 이게 반환
ControllerV1 controller = controllerMap.get(requestURI);
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
controller.process(request, response);
}
}
url창에서 잘 보인다. 완벽하다.
다형성에 의해서
public class MemberListControllerV1 implements ControllerV1 {
부모로 부터 받을 수 있다.
ControllerV1 controller = controllerMap.get(requestURI);
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
// ControllerV1 controller = MemberListControllerV1
이 부분도 같이 보면 404가 떨어져야 하지만
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
계속해서 failed가 떨어지게 된다. 상태코드 Status Code를 보게되면 404로 나와있다.
즉 Servlet에서는 호출이 됐는데
String requestURI = request.getRequestURI();
Map에서 찾는데 없다. 그러면 상태코드를 404로 바꾸고 return해버린다.
// ControllerV1 controller = MemberListControllerV1
ControllerV1 controller = controllerMap.get(requestURI);
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
// 실행 콘솔창 FrontControllerServletV1.service
클라이언트가 HTTP 요청을 하면 Front Controller이 매핑 정보에서 URL 매핑 정보에서 컨트롤러를 조회한다.
Front Controller에서 Controller를 호출하고 Controller는 JSP로 VIEW형태로 포워딩한다.
그리고 HTML 응답을 하게된다.
매우 중요하다.
구조적인거 큰그림 개선 commit 배포단계에서 확인 끝 => 그 다음 단계에서 세밀한 부분 작은그림을 수정 commit
<출처 김영한: 스프링 MVC 1편 - 벡앤드 웹 개발 핵심 기술>
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의
웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -
www.inflearn.com
'Spring > SpringMVC' 카테고리의 다른 글
Model 추가 - v3 (0) | 2022.04.24 |
---|---|
View 분리 - v2 (0) | 2022.04.24 |
MVC 프레임워크 만들기 (0) | 2022.04.23 |
MVC 패턴 - 한계 (0) | 2022.04.23 |
MVC 패턴 - 개요 - error (0) | 2022.04.23 |