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
반응형
'Spring > spring framework 구현 스터디' 카테고리의 다른 글
[Spring] 프론트 컨트롤러 7 : 정리 (0) | 2021.10.30 |
---|---|
[Spring] 프론트 컨트롤러 6 : 어댑터 추가 (0) | 2021.10.30 |
[Spring] 프론트 컨트롤러 4 : 개선편 (0) | 2021.10.26 |
[Spring] 프론트 컨트롤러 3 : 종속성제거, 뷰리졸버 구현 (0) | 2021.10.23 |
[Spring] 프론트 컨트롤러 2 : 적용, 뷰 분리 (0) | 2021.10.21 |
댓글