앞의 FrontController 구조에서 뷰를 분리하여 코드의 반복을 없앨 수 있다.
MyView
package hello.servlet.web.frontcontroller;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyView {
private String viewPath;
public MyView(String viewPath) {
this.viewPath = viewPath;
}
public void render(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
}
}
기존의 모든 컨트롤러에서 뷰를 이동하는 부분에 중복이 있었다.
viewPath를 받아와서 뷰를 렌더링할 수 있는 MyView 객체를 생성한다.
ControllerV2
package hello.servlet.web.frontcontroller.v2;
import hello.servlet.web.frontcontroller.MyView;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public interface ControllerV2 {
MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
컨트롤러 인터페이스에서 process 메소드의 반환타입을 MyView로 설정해준다.
MemberFormControllerV2
package hello.servlet.web.frontcontroller.v2.controller;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v2.ControllerV2;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MemberFormControllerV2 implements ControllerV2 {
@Override
public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
return new MyView("/WEB-INF/views/new-form.jsp");
}
}
V1 구조에서의 MemberFormController에서 다른 점은, 간편하게 렌더링할 jsp 페이지를 MyView 객체를 생성하며 간편하게 뷰를 렌더링한다는 것이다.
MemberSave, MemberList 컨트롤러도 이와 비슷하게 구현하면 된다. 기존의 V1 구조에서 뷰를 렌더링하는 반복되는 부분이 사라졌다.
FrontControllerServletV2
package hello.servlet.web.frontcontroller.v2;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v2.controller.MemberFormControllerV2;
import hello.servlet.web.frontcontroller.v2.controller.MemberListControllerV2;
import hello.servlet.web.frontcontroller.v2.controller.MemberSaveControllerV2;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@WebServlet(name = "frontControllerServletV2", urlPatterns = "/front-controller/v2/*")
public class FrontControllerServletV2 extends HttpServlet {
private Map<String, ControllerV2> controllerMap = new HashMap<>();
public FrontControllerServletV2() {
controllerMap.put("/front-controller/v2/members/new-form", new MemberFormControllerV2());
controllerMap.put("/front-controller/v2/members/save", new MemberSaveControllerV2());
controllerMap.put("/front-controller/v2/members", new MemberListControllerV2());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("FrontControllerServletV2.service");
String requestURI = request.getRequestURI();
ControllerV2 controller = controllerMap.get(requestURI);
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
MyView view = controller.process(request, response);
view.render(request, response);
}
}
이제 Controller의 process 메소드가 MyView 객체를 반환하므로 MyView의 render를 호출하여 jsp를 실행한다.
'BackEnd : Spring > Spring MVC' 카테고리의 다른 글
[Spring MVC] FrontController : 단순하고 실용적인 컨트롤러 (0) | 2024.04.08 |
---|---|
[Spring MVC] FrontController : Model 추가하기 (0) | 2024.04.06 |
[Spring MVC] FrontController 패턴 생성하기 (0) | 2024.04.06 |
[Spring MVC] HttpServletResponse, Http 응답 데이터 (0) | 2024.03.23 |
[Spring MVC] HTTP 요청 데이터 (0) | 2024.03.20 |