[Spring Web MVC] Front Controller
프론트 컨트롤러를 도입해 공통되는 요소를 하나로 묶어서 처리할 수 있다.
프론트 컨트롤러 역할을 수행하는 서블릿 하나로 클라이언트의 요청을 받고, 프론트 컨트롤러가 요청에 맞는 컨트롤러를 찾아서 호출한다.
해당 컨트롤러만 서블릿으로 등록해서 사용할 수 있어 편리하다.
public interface ControllerV1 {
void process(HttpServletRequest request , HttpServletResponse response) throws IOException, ServletException;
}
서블릿과 비슷한 형태의 컨트롤러 인터페이스를 도입하자.
각 컨트롤러들은 해당 인터페이스를 구현하고, 프론트 컨트롤러는 인터페이스를 호출해 구현에 상관 없이 로직의 일관성을 가진다.
@WebServlet(name = "zaweq12", urlPatterns = "/front-controller/v1/*") // *으로 어떤게 들어와도 일단 호출하게 함
public class FrontControllerServletV1 extends HttpServlet {
private Map<String, ControllerV1> controllerV1Map = new HashMap<>();
public FrontControllerServletV1(Map<String, ControllerV1> controllerV1Map) {
controllerV1Map.put("/front-controller/v1/members/new-form", new MemberFormControllerV1());
controllerV1Map.put("/front-controller/v1/members/save", new MemberSaveControllerV1());
controllerV1Map.put("/front-controller/v1/members", new MemberListControllerV1());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("launch test");
String requestURI = request.getRequestURI(); // 요청 URI 꺼내
ControllerV1 controller = controllerV1Map.get(requestURI); // 해당하는 컨트롤러 찾아
if(controller == null){
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
controller.process(request, response);
}
}
클라이언트로부터 요청이 오면 매핑된 정보로 어떤 컨트롤러를 호출할 지 찾고 해당 컨트롤러를 실행한다.
화면을 내려주는 작업도 간단하게 바꿔보자.
public class MyView {
private String viewPath;
public MyView(String viewPath) {
this.viewPath = viewPath;
}
public void render(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath); // 모델 역할을 함
dispatcher.forward(request, response);
}
}
@WebServlet(name = "zaweq132", urlPatterns = "/front-controller/v2/*") // *으로 어떤게 들어와도 일단 호출하게 함
public class FrontControllerServletV2 extends HttpServlet {
private Map<String, ControllerV2> controllerV2Map = new HashMap<>();
public FrontControllerServletV2() {
controllerV2Map.put("/front-controller/v2/members/new-form", new MemberFormControllerV2());
controllerV2Map.put("/front-controller/v2/members/save", new MemberSaveControllerV2());
controllerV2Map.put("/front-controller/v2/members", new MemberListControllerV2());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("launch test");
String requestURI = request.getRequestURI(); // 요청 URI 꺼내
ControllerV2 controller = controllerV2Map.get(requestURI); // 해당하는 컨트롤러 찾아
if(controller == null){
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
System.out.println(requestURI);
return;
}
MyView view = controller.process(request, response);
view.render(request, response);
}
}
MyView 객체를 통해 화면을 그리는 작업을 정리했다.
컨트롤러는 프론트 컨트롤러에게 MyView에 viewPath를 넣어서 건내준다.
이후 프론트 컨트롤러에서 render 메서드를 호출해 화면을 렌더링한다.
모듈별로 서블릿을 등록해두면 서블릿마다 독립적인 설정이 가능하지만, 서블릿이 많이 생성되는 경우 관리 비용이 증가하고 복잡성이 증가한다.
반면 이렇게 프론트 컨트롤러 패턴을 사용하면 중복 코드를 최소화하고 재사용성을 높일 수 있어 인증, 로깅 등 공통 처리가 필요한 부분을 한 번에 처리할 수 있다.
반응형
'Spring > Spring Web MVC' 카테고리의 다른 글
[Spring Web MVC] Spring MVC (0) | 2022.08.16 |
---|---|
[Spring Web MVC] Adaptor (0) | 2022.08.16 |
[Spring Web MVC] Model (0) | 2022.08.15 |
[Spring Web MVC] 서블릿과 HTTP 통신 (0) | 2022.08.14 |
[Spring Web MVC] 웹 애플리케이션 (0) | 2022.08.13 |
댓글
이 글 공유하기
다른 글
-
[Spring Web MVC] Adaptor
[Spring Web MVC] Adaptor
2022.08.16 -
[Spring Web MVC] Model
[Spring Web MVC] Model
2022.08.15 -
[Spring Web MVC] 서블릿과 HTTP 통신
[Spring Web MVC] 서블릿과 HTTP 통신
2022.08.14 -
[Spring Web MVC] 웹 애플리케이션
[Spring Web MVC] 웹 애플리케이션
2022.08.13