Front Controller를 추가해서 구조를 맞추고 리펙터링 해 나간다.
프론트 컨트롤러를 추가하면 클라이언트가 HTTP 요청을 넣었을 때 프론트 컨트롤러가 받고 URL 매핑 정보에서 컨트롤러를 조회한 뒤 알맞는 컨트롤러를 호출해 주게 된다. 그럼 호출된 컨트롤러가 JSP forward를 통해 JSP로 보내주고 HTML 응답을하게 되는 것이다.
public interface ControllerV1 {
void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, 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);
}
}
회원 정보 등록을 위한 form 컨트롤러 코드만 다 보면 이렇다. 비슷하게 저장과 목록 컨트롤러도 생성해주고 전에 사용한 코드를 복사해와서 붙여넣기로 넣어둔다. 내부 로직은 거의 비슷하다고 보면 되고 프론트 컨트롤러 단을 잘 보면 된다.
프론트 컨트롤러 단이다.
@WebServlet(name = "frontControllerServletV1", urlPatterns = "/front-controller/v1/*")
urlPatterns을 보면 조금 특이하게 되어 있는데 *이 있다. *전까지 같은 URL을 포함한 하위 모든 요청을 이 서블릿에서 받는다는 말이다. 쉽게 말하면 /front-controller/v1까지 같은 모든 요청을 가져온다고 보면 된다.
public class FrontControllerServletV1 extends HttpServlet
프론트 컨트롤러는 HttpServlet을 상속 받는다.
private Map<String, ControllerV1> controllerMap = new HashMap<>();
key는 String으로 매핑 URL을 담는다. value는 호출된 컨트롤러를 담아준다.
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());
}
키 값의 URL이 들어오면 벨류 값의 컨트롤러를 호출하는 형식이다. 저장해 두었다가 요청이 들어오면 사용한다.
String requestURI = request.getRequestURI();
URI를 기준으로 값을 꺼낼 수 있다.
ControllerV1 controller = controllerMap.get(requestURI);
requestURI를 꺼내면 HashMap을 통해 컨트롤러가 찾아진다.
다형성에 의해 인터페이스를 받을 수 있다.
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
requestURI에서 조회해서 실제 호출할 컨트롤러를 controllerMap에서 찾는데 만약 찾는 값이 없다면 HttpServletResponse에서 제공하는 SC_NOT_FOUND를 통해 404오류를 띄워줄 수 있다.
controller.process(request, response);
마지막으로 아까 위에서 만든 인터페이스 컨트롤러에서 정의한 process를 호출해 주고 코드가 마무리된다.
스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술을 참고하여 공부하였습니다.
'Framework & Library > Spring Boot' 카테고리의 다른 글
[Spring Boot] : Model 추가해서 Front Controller에서만 Servlet 사용하기 (0) | 2022.01.22 |
---|---|
[Spring Boot] : Controller에서 View 이동 시 중복되는 부분 리펙터링하기 (0) | 2022.01.22 |
[Spring Boot] : Front Controller란? (0) | 2022.01.21 |
[Spring Boot] : MVC 패턴 적용해보고 한계 체크하기(3) (0) | 2022.01.21 |
[Spring Boot] : MVC 패턴 적용해보고 한계 체크하기(2) (0) | 2022.01.21 |
댓글