Free Lines Arrow
본문 바로가기
Spring/spring framework 구현 스터디

[Spring] 프론트 컨트롤러 6 : 어댑터 추가

by skahn1215 2021. 10. 30.
728x90
반응형

어댑터 추가

앞서 구현했던 버전에서 ControllerV4 어댑터를 만들고 FrontController 에 추가해보자.

 

 

ControllerV4HandlerAdapter

  • 앞에서 만든 ControllerV3HandlerAdapter 와 구조는 비슷하지만
    어댑터 부분에 차이가 있다.
public class ControllerV4HandlerAdapter implements MyHandlerAdapter {
    @Override
    public boolean supports(Object handler) {
        return (handler instanceof ControllerV4);
    }

    @Override
    public ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        ControllerV4 controller = (ControllerV4)handler;
        Map<String, String> paramMap = createParamMap(request);

        HashMap<String, Object> model = new HashMap<>();
        String viewName = controller.process(paramMap, model);


        // 어댑터 역할을 한다.
        // 뷰네임 을 모델로 변환시켰다.
        ModelView mv = new ModelView(viewName);
        mv.setModel(model);

        return mv;
    }

    // 레벨을 맞춰주기 위해 메서드로 뽑아준다.
    private Map<String, String> createParamMap(HttpServletRequest req) {
        // paramMap을 넘겨줘야한다.
        Map<String, String> paramMap = new HashMap<>();
        req.getParameterNames().asIterator()
                .forEachRemaining(paramName -> paramMap.put(paramName, req.getParameter(paramName)));
        return paramMap;
    }
}

 

 

아래코드가 중요하다.

  • 기존컨트롤러 V4 는 뷰네임을 반환한다.
  • 하지만 프론트컨트롤러에는 모델을 반환해 줘야한다.
  • 그래서 모델을 생성하는 작업이 추가가 되었다.
        String viewName = controller.process(paramMap, model);
        // 어댑터 역할을 한다.
        // 뷰네임 을 모델로 변환시켰다.
        ModelView mv = new ModelView(viewName);
        mv.setModel(model);

 

 

FrontController

  • 프론트 컨틀러에서 추가된 부분은 단 2군데 뿐이다.
  • initHandlerMappingMap();
  • initHandlerAdapters();
  • 또 추가될 어댑터가 있으면 두함수에만 추가해주면된다.
package hello.servlet.web.frontcontroller.v5;

import hello.servlet.web.frontcontroller.ModelView;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v3.controller.MemberFormControllerV3;
import hello.servlet.web.frontcontroller.v3.controller.MemberListControllerV3;
import hello.servlet.web.frontcontroller.v3.controller.MemberSaveControllerV3;
import hello.servlet.web.frontcontroller.v4.controller.MemberFormControllerV4;
import hello.servlet.web.frontcontroller.v4.controller.MemberListControllerV4;
import hello.servlet.web.frontcontroller.v4.controller.MemberSaveControllerV4;
import hello.servlet.web.frontcontroller.v5.adapter.ControllerV3HandlerAdapter;
import hello.servlet.web.frontcontroller.v5.adapter.ControllerV4HandlerAdapter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

@WebServlet(name = "frontControllerServletV5", urlPatterns = "/front-controller/v5/*")
public class FrontControllerV5 extends HttpServlet {

    // 기존 과 차이점은 모든 컨트롤러를 다뤄야 하기때문에 Object 로 하였다.
    private final Map<String, Object> handlerMappingMap = new HashMap<>();
    private final List<MyHandlerAdapter> handlerAdapters = new ArrayList<>();

    public FrontControllerV5() {
        initHandlerMappingMap();
        initHandlerAdapters();
    }

    private void initHandlerMappingMap() {
        handlerMappingMap.put("/front-controller/v5/v3/members/new-form", new MemberFormControllerV3());
        handlerMappingMap.put("/front-controller/v5/v3/members/save", new MemberSaveControllerV3());
        handlerMappingMap.put("/front-controller/v5/v3/members", new MemberListControllerV3());

        // V4 추가된부분
        handlerMappingMap.put("/front-controller/v5/v4/members/new-form", new MemberFormControllerV4());
        handlerMappingMap.put("/front-controller/v5/v4/members/save", new MemberSaveControllerV4());
        handlerMappingMap.put("/front-controller/v5/v4/members", new MemberListControllerV4());
    }

    private void initHandlerAdapters() {
        handlerAdapters.add(new ControllerV3HandlerAdapter());
        
        // V4 추가된부분
        handlerAdapters.add(new ControllerV4HandlerAdapter());
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // req 의 uri 에 맞는 파악한뒤 핸들러를 가져온다.
        Object handler = gerHandler(req);

        if (handler == null) {
            resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        // 핸들러 어뎁터를 찾아온다.
        MyHandlerAdapter adapter = getHandlerAdapter(handler);

        ModelView mv = adapter.handle(req, resp, handler);

        // 뷰리졸버 구현 논리 이름을 물리 이름으로 변경해야 된다.
        String viewName = mv.getViewName();
        MyView view = viewResolver(viewName);

        view.render(mv.getModel(), req, resp);
    }

    private MyHandlerAdapter getHandlerAdapter(Object handler) {
        for (MyHandlerAdapter adapter : handlerAdapters) {
            if (adapter.supports(handler)) {
                return adapter;
            }
        }
        throw new IllegalArgumentException("handler adapter를 찾을수 없습니다."+handler);
    }

    private Object gerHandler(HttpServletRequest req) {
        String requestURI = req.getRequestURI();
        return handlerMappingMap.get(requestURI);
    }

    private MyView viewResolver(String viewName) {
        MyView view = new MyView("/WEB-INF/views/" + viewName + ".jsp");
        return view;
    }
}

 

 

 

참고

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/lecture/71196?tab=note 

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 학습 페이지

지식을 나누면 반드시 나에게 돌아옵니다. 인프런을 통해 나의 지식에 가치를 부여하세요....

www.inflearn.com

 

728x90
반응형

댓글