Controller 매핑 정보를 담을 controllerMap 생성
{/front-controller/v3/members/new-form : MemberFormControllerV3}
, {/front-controller/v3/members/save : MemberSaveControllerV3}
,{/front-controller/v3/members:MemberListControllerV3}
put
http://localhost:8080/front-controller/v3/members/new-form
FrontControllerServletV3.service()
String requestURI = request.getRequestURI();
요청 URI 정보를 받아옴
ControllerV3 controller = controllerMap.get(requestURI);
if(controller == null){//controller가 없으면
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
controller 매핑 정보가 담긴 controllerMap에서 요청받은 URI를 key로 가진 컨트롤러를 찾아온다. ~ new-form 이 입력됐으니, MemberFromControllerV3를 가져옴
만약 URI가 잘못 입력되어 없다면 404 상태코드를 보냄
Map<String, String> paramMap = createParamMap(request);
request의 정보를 모두 paramMap에 담는다.
ModelView mv = controller.process(paramMap);
MemberFormControllerV3의 process 실행 -> 컨트롤러 실행
return new ModelView("new-form");
ModelView를 생성하고 view의 논리이름인 "new-form"을 담아 반환한다. form에선 model이 따로 필요없으므로 담을 필요도 없다.
String viewName = mv.getViewName();
process에서 반환한 논리이름을 가져온다. 여기선 new-form이 되겠다.
MyView view = viewResolver(viewName);
viewResolver 실행하여 물리 이름을 반환받는다.
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
논리 이름에 prefix와 suffix를 붙여 반환한다. /WEB-INF/views/new-form.jsp
가 반환된다
view.render(mv.getModel(), request, response);
forward한다.
modelToRequestAttribute(model, request);
JSP에선 getAttribute를 통해 저장된 데이터를 사용하기 때문에 model의 정보를 request에 setAttribute 해줘야한다.
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
jsp 파일로 forward 한다.
private final Map<String, Object> handlerMappingMap = new HashMap<>();
핸들러 매핑 정보를 담은 hadlerMappingMap 생성, 어떤 것이 올 지 모르므로 Object
private final List<MyHandlerAdapter> handlerAdapters = new ArrayList<>();
핸들러 어댑터 정보들을 담을 handlerAdapters 생성
public FrontControllerServletV5() {
initHandlerMappingMap();
initHandlerAdapters();
}
initHandlerMappingMap();
핸들러 매핑 정보를 넣는다. key엔 URI, value엔 핸들러를 생성해서 담는다.
initHandlerAdapters();
어댑터 정보를 넣는다.
http://localhost:8080/front-controller/v5/v3/members/new-form
FrontControllerServletV5.service()
Object handler = getHandler(request);
요청URI를 통해 핸들러매핑 정보에서 핸들러를 조회한다. 위의 경우엔 v3/members/new-form
이므로 MemberFormControllerV3가 handler에 담긴다.
MyHandlerAdapter adapter = getHandlerAdapter(handler);
handelr에 맞는 어댑터를 찾아 adapter에 담는다.
private MyHandlerAdapter getHandlerAdapter(Object handler) {
for (MyHandlerAdapter adapter : handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
throw new IllegalArgumentException("handler adapter를 찾을 수 없습니다.");
}
핸들러 어댑터 정보에서 하나씩 빼서 supports를 이용해 handler가 어댑터와 맞으면 반환한다.
public boolean supports(Object handler) {
return (handler instanceof ControllerV3);
}
instanceof 를 통해 해당 handler를 ControllerV3가 처리할 수 있는지 확인한다. 지금은 handler가 MemberFormControllerV3로 ControllerV3로 처리할 수 있으므로 True를 반환한다.
ModelView mv = adapter.handle(request, response, handler);
adapter를 실행한다.
ControllerV3 controller = (ControllerV3) handler;
Object 였던 handler를 ControllerV3로 캐스팅 한다. 이전에 instanceof로 타입확인을 했으니 캐스팅해도 상관없다. Map<String, String> paramMap = createParamMap(request);
request의 정보를 paramMap에 담는다. ModelView mv = controller.process(paramMap);
controller의 pocess를 실행하고 ModelView를 반환받는다. return new ModelView("new-form");
ModelView를 생성하고 view의 논리이름인 "new-form"을 담아 반환한다. form에선 model이 따로 필요없으므로 담을 필요도 없다. String viewName = mv.getViewName();
논리이름을 가져와 viewName에 담는다. 따라서 viewName엔 new-form이 담겨있다.
MyView view = viewResolver(viewName);
viewResolver를 통해 논리 이름을 물리 이름으로 변환한다.
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
논리 이름에 prefix와 suffix를 붙여 반환한다. /WEB-INF/views/new-form.jsp
가 반환된다. view.render(mv.getModel(), request, response);
forward한다.
modelToRequestAttribute(model, request);
JSP에선 getAttribute를 통해 저장된 데이터를 사용하기 때문에 model의 정보를 request에 setAttribute 해줘야한다.
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request, response);
jsp 파일로 forward 한다.
자세한 것은 스프링 프레임워크 만들기 v3와 스프링 프레임워크 만들기 v5를 참고하자.