MapleStory Cookie With Halo

☕ JAVA/☕ Library & Pattern

[JAVA]어댑터 패턴을 도입해 유연한 컨트롤러를 만들어보자

뉴이 NUEY 2025. 3. 1. 23:45
반응형

 

이전 코드를 개선하기 위해 어댑터 패턴을 사용할 것이다.
여러 컨트롤러를 자유롭게 사용할 수 있는 유연한 컨트롤러를 만들어보자.

※ 이전 글 

2025.03.01 - [☕ JAVA/☕ Library & Pattern] - [JAVA]MVC의 Model 만들어보기

 

 

  • 핸들러 어댑터

    • 중간 어댑터 역할.
    • 덕분에 여러 컨트롤러 호출 가능.

  • 핸들러

    • 컨트롤러가 할 수 있는 영역을 넓힌 것.
      (컨트롤이라 생각하면된다)

 


 

  1. 폴더와 경로
    v3에 만들었던 컨트롤러를 모두 호출할 수 있는 어댑터를 만들어보려 한다.따
    딱 이 세개만 만들면 됨.

  2. 프론트 컨트롤러
    1. 프론트 컨트롤러가 생성자로 바로 함수 두개를 실행해 map두개에 값을 답아줍니다.
      전체코드는 포스트 하단에 두겠습니다. 갑자기 안들어가네요ㅎ


    2. handler(컨트롤러)를 adapter로 보내고, 어댑터의 handle()을 이용해 ModelVeiw를 반환 받습니다.
      나머지는 이전 코드와 거의 동일합니다.
      그럼 어댑터에서 뭐하는 지 알아봅시다.
  3. 어댑터의 조상.
    컨트롤러들을 호출할 interface 형태.
    package hello.servlet.web.frontcontroller.v5;
    
    import java.io.IOException;
    
    import hello.servlet.web.frontcontroller.ModelView;
    import jakarta.servlet.ServletException;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
    
    public interface MyHandlerAdapter {
    
        boolean supports(Object handler);
    
        ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException;
    }


  4. 어댑터는 컨트롤러를 받아서 뭐하는 지.
    더보기
    package hello.servlet.web.frontcontroller.v5.adapter;
    
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    
    import hello.servlet.web.frontcontroller.ModelView;
    import hello.servlet.web.frontcontroller.v3.ControllerV3;
    import hello.servlet.web.frontcontroller.v5.MyHandlerAdapter;
    import jakarta.servlet.ServletException;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
    
    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 controllerV3 = (ControllerV3) handler;
            
            Map<String, String> paramMap = createParam(request);
            ModelView mv = controllerV3.process(paramMap);
    
            return mv;
        }
    
        private Map<String, String> createParam(HttpServletRequest request) {
            Map<String, String> paramMap = new HashMap<>();
            request.getParameterNames().asIterator()
                    .forEachRemaining(paramName -> paramMap.put(paramName, request.getParameter(paramName)));
            return paramMap;
        }
    }
    • supports(Object handler)
      → ControllerV3의 인스턴스인 지 확인.

    • paramMap형태로 데이터를 전달하면서 컨트롤러를 실행합니다.


 

프론트 컨트롤러 코드

더보기
package hello.servlet.web.frontcontroller.v5;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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.v5.adapter.ControllerV3HandlerAdapter;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

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

    private final Map<String, Object> handlerMappingMap = new HashMap<>();
    private final List<MyHandlerAdapter> handlerAdapters = new ArrayList<>();

    public FrontControllerServletV5() {
        initHandlerMappingMap();
        initHandlerAdapter();
    }

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

    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());
    }

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        Object handler = getHandler(request);
        if (handler == null) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            return;
        }

        MyHandlerAdapter adapter = getHandlerAdapter(handler);

        ModelView mv = adapter.handle(request, response, handler);

        String viewName = mv.getViewName();
        MyView view = viewResolver(viewName);
        
        view.render(mv.getModel(), request, response);
    }

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

    private MyHandlerAdapter getHandlerAdapter(Object handler) {
        for (MyHandlerAdapter adapter : handlerAdapters) {
            if (adapter.supports(handler)) {
                return adapter;
            }
        }
        throw new IllegalArgumentException("Handler adapter not found. handler=" + handler);
    }

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

 


※ 참조 : https://www.inflearn.com/roadmaps/373

반응형