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

[Spring] 프론트 컨트롤러 5 : 어댑터 적용

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

어댑터 적용

  • 어댑터 패턴을 적용해본다.
  • 적용하는 이유는 사용자마다 V4 또는 V5 를 선택해서 사용하게 하려고 한다.
  • 어댑터 패턴 예제
     - https://vprog1215.tistory.com/261

 

 

어댑터를 적용한 구조

  • 핸들러 매핑정보:
    요청에 대한 정보를 담는다. 요청된 url 을 key 로 컨트롤러를 value 로 갖는다.
  • 핸들러 어댑터 목록:
    핸들러 매핑정보에서 가져온 컨트롤러를 처리할 어댑터를 담고 있는다.
  • 핸들러 어댑터:
    반환된 핸들러 어댑터에서 핸들러를 처리한다.

 

 

 

MyHandler Adapter

  • 어댑터를 구현하기 위한 인터페이스이다.
  • supports:
     - 구현체가 해당 핸들러를 지원하는지 확인한다.
  •  handle:
     - 핸들러를 조회한뒤 
public interface MyHandlerAdapter {
    boolean supports(Object handler);
    ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException;
}

 

 

ControllerV3HandlerAdapter

위 그림에서 핸들러 어댑터 부분이다.

  • 실제 핸들러 어댑터 구현체이다.
  • supports:
     - 해당 부분에서 컨틀로러의 인스턴스인지 확인한다.
  • handle:
     - 받아온 핸들러를 ControllerV3 로 캐스팅한다.
     - modelview 를 넘긴다.
  • createParamMap:
     - req 의 정보를 맵으로 담아 반환한다.
     -  controllerV3 는 process 시 맵을 받기 때문이다.
public class ControllerV3HandlerAdapter implements MyHandlerAdapter {

    @Override
    public boolean supports(Object handler) {
        return (handler instanceof ControllerV3);
    }

    @Override
    public ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        ControllerV3 controller = (ControllerV3) handler;

        Map<String, String> paramMap = createParamMap(request);
        ModelView mv = controller.process(paramMap);
        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;
    }
}

 

 

FrontControllerV5

  • FrontControllerV5
     - 맵핑 정보를 맵에 담고 어댑터를 List 에 담는다.
  • service:
     - getHandler(): request uri 에 해당하는 컨트롤러를 가져온다.
  • getHandlerAdapter:
     - parameter 로 넘어온 컨트롤러가 저장된 컨트롤러 어댑터의 컨트롤러의 인스턴스인지 확인한다.
     - ControllerV3HandlerAdapter.supports() 는 controllerV3 의 인스턴스인지 확인한다.
  • adapter.handle(req, res, hanlder)
     - adapter는 ControllerV3HandlerAdapter 객체이다.
     - ControllerV3HandlerAdapter.handle(req, res, handler) 로 이해하면 된다.
     - 실제 컨트롤러를 수행하여 modelview 를 반환한다.
@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());
    }

    private void initHandlerAdapters() {
        handlerAdapters.add(new ControllerV3HandlerAdapter());
    }

    @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 

 

728x90
반응형

댓글