[MVC1] 스프링 MVC(1)

gayoung·2022년 10월 29일
0

스프링 완전 정복

목록 보기
32/33

1. MVC패턴

1-1. 개요

  • Servlet, JSP만으로 비즈니스 로직, 뷰랜더링까지 모두 처리하면 너무 많은 역할을 가지고있어 유지보수 어려움
  • JSP 같은 뷰 템플릿은 화면을 렌더링 하는데 최적화 -> 화면 렌더링 역할만 맡기
  • M: 뷰에 출력할 데이터를 담아두기
    V: 델에 담겨있는 데이터를 사용해서 화면을 그림(HTML생성)
    C: HTTP 요청을 받아서 파라미터를 검증하고, 비즈니스 로직을 실행 + 뷰에 전달

1-2. 한계

  • 포워드 중복: view로 이동하는 코드가 항상 중복호출됨
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
  • viewPath 중복: String viewPath = "/WEB-INF/views/new-form.jsp";
  • 사용하지 않는 코드 존재: HttpServletRequest request, HttpServletResponse response
  • 공통처리가 어려움

2. MVC 프레임워크 만들기

2-1. V1 프론트 컨트롤러 도입

  • 각각의 Controller는 ControllerV1 가지고온다 (service는 컨트롤러 찾아주는 용도+process는 컨트롤러 실행)
  • FrontController : /front-controller/v1/하위의모든url에 호출됨
    => controllerMap 으로 (매핑url, 호출된 컨트롤러)를 가지고오기
    => requestURI를 조회해서 실제 호출할 컨트롤러 찾음
    => controller.process를 호출해 해당 컨트롤러 실행

2-2. V2 View 분리

  • 각각의 Controller에서 View 반환(MyView)
  • FrontController : controller.process를 호출할 때 MyView를 반환함
    => view.render를 호출해 forward 로직을 수행해서 jsp로 넘어가서 화면보여줌
    모든 컨트롤러마다 request.getRequestDispatcher(viewPath);
    dispatcher.forward(request, response); 가 있었는데,
    => 이를 컨트롤러마다 return new MyView("/WEB-INF/views/members.jsp");로 바꾸고
    => FrontController에서 MyView view = controller.process(request, response); view.render(request, response); 으로 넘겨줌

2-3. V3 Model 추가

[ 목적 ]

- 서블릿 종속성 제거 -> service의 HttpServletRequest, HttpServletResponse가 꼭 필요한가?
                      -> 요청파라미터 정보를 Map으로 넘기면 없어도 됨 => Model객체로 반환
 - 뷰이름 중복 제거: /WEB-INF/views/new-form.jsp => new-form : 뷰의 논리 이름
                    => 뷰의 물리이름은 프론트컨트롤러에서 처리

  • FrontController : MemberFormControllerV3 호출 해야하는데 그 전에 createParamMap함수에서
    HttpServletRequest에 있는 모든 parameter 가지고오기 => 각각 Controller에서 ModelView 객체반환 논리이름(new-form)을 가지고 옴 => makeView함수에서논리이름 -> 물리이름(전체주소)으로바꿔줌
    (myView=전체주소반환, viewResolver는 물리이름으로 변환시켜주는 함수) => myView를가지고모델을같이넘기면서render진행
    render할 때 ModelView의 객체도 같이 넘겨주기

2-4. V4 단순하고 실용적인 컨트롤러

  • Controller에서 ModelView가 아닌 ViewName만 반환(return "save-result")
    V3: 모델안에 있는 값을 가지고와서 바꿔줬다면,

    V4: String으로 가지고 옴

  • V3: String process(Map<String, String> paramMap);
    V4: String process(Map<String, String> paramMap, Map<String, Object> model);

  • 모델 객체 전달: Map<String, Object> model = new HashMap<>();
    V3: 모델 객체를 각각 컨트롤러에서 생성
    V4: 모델 객체를 프론트 컨트롤러에서 생성 (컨트롤러에서 모델 객체에 값을 담으면 여기에 담김)

2-5. V5 유연한 컨트롤러

[ 목적 ]

- 어떤사람은 V3, 어떤사람은 V4로 만들고싶어함
      핸들러 어댑터: 다양한 종류의 컨트롤러 호출 가능
      핸들러: 컨트롤러

  • ControllerV3HandlerAdapter, ControllerV4HandlerAdapter는 MyHandlerAdapter를 오버라이드함
    supports는 V3, V4 넘어올 때 지원가능한지 여부 확인
    handle에서는 V3, V4 각각 변경시켜주고 modelView반환시키기

  • FrontController: handlerMappingMap - 아무컨트롤러나다들어갈수있음(Object) -> V3의 물리적주소
    handlerAdapters - 여러 adapter 중 하나 꺼내써야함
    service - handler 조회(handlerMappingMap에서 requestURI가지고오기)
    => handlerAdapter조회 (MyHandlerAdapter) => handle호출해서 ModelView반환
    => 경로(/WEB-INF/views/members.jsp)찾기(viewResolver로 앞,뒤 주소붙이기)
    => view,render 호출

  • doDispatch가 handler, controller찾아주는 역할

0개의 댓글