단계별로 MVC를 발달시켜서 왜 현 스프링 MVC가 만들어졌는지 이해해보겠다.
이전글에서도 봤지만, 공통로직 (response, request 처리)같은 경우 모든 Controller에 전부 들어가게 되었다. 따라서 이를 공통적으로 처리해줄 컨트롤러가 요구되게 되었고, 이에 Front Controller가 도입되었다.
Servlet과 유사한 모습의 컨트롤러 인터페이스를 만든다.
public interface ControllerV1 {
void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
}
FrontController가 공통부분을 시행하고, 매핑정보를 보고 FrontController가 어떤 컨트롤러로 연결해줘야 하는지 찾는다.
각 컨트롤러를 MVC 컨트롤러에서 사용한 로직을 그대로 사용한다.
하지만 이 방식으로는 딱히 코드가 개선된건 없고 그냥 FrontController가 추가된 정도이다.
이제 V2를 보겠다.
MyView라는 공통 랜더링 클래스를 만들어준다.
public class MyView {
private String viewPath;
public MyView(String viewPath) {
this.viewPath = viewPath;
}
public void render(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher requestDispatcher = request.getRequestDispatcher(viewPath);
requestDispatcher.forward(request, response);
}
}
아직 Model이라는 개념이 도입되지 않았고 불필요한 코드가 조금 있다. 다음 V3에서는 이 부분들을 개선해볼 것이다.
요청 파라미터 정보를 맵으로 대신 머기도록 하면, 컨트롤러가 서블릿을 몰라도 동작할 수 있다.
그리고 request를 Model로 사용하는대신, 별도의 Model을 만들어서 반환할수 있다.
그리고 View에 들어가는 URI를 없앨것이다.
모델뷰는 서블릿의 종속성을 제거하기 위해 Model을 직접 만들고, 추가로 View 이름까지 전달하는 객체이다.
modelview는 뷰의 이름과 뷰를 렌더링할 때 필요한 model 객체를 가지고 있다. model은 단순히 map으로 되어
있기에 컨트롤러에서 뷰에 필요한 데이터를 key, value로 넣어주면 된다.
각 컨트롤러들은 modelView에 자신의 jsp이름을 넣어서 반환해준다. 그러면 이 이름들은 FrontController의 viewResolver에 의하여 경로로 변환된다.
가입 요청이 들어온다
FrontControllerV3 Servlet이 작동한다
URI에 맞는 Controller객체가 호출 된다
그 전에 createParam을 통해 HttpServlet Request에
있는 파라미터를 전부 뽑아서 paramMap을 만들어서 반환한다
ModelView에서 각 Controller의 동작을 수행하고 model name을 반환받는다
viewResolver를 호출해서 진짜 물리주소로 만들어낸다.
view가 랜더를 호출하면서 모델정보, request, response 를 전부 넘겨준다.
render에서는 request를 전부 setAttribute 처리한다.
Dispatch해서 처리한다.