public class MemberSaveControllerV3 implements ControllerV3 {
MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public ModelView process(Map<String, String> paramMap) {
String username = paramMap.get("username");
int age = Integer.parseInt(paramMap.get("age"));
Member member = new Member(username, age);
memberRepository.save(member);
ModelView modelView = new ModelView("save-result");
modelView.getModel().put("member", member);
return modelView;
}
}
V3의 경우 view파일 이름, view파일에 전달할 model을 모아 modelView를 생성해 반환한다.
public class MemberSaveControllerV4 implements ControllerV4 {
MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public String process(Map<String, String> paramMap, Map<String, Object> model) {
String username = paramMap.get("username");
int age = Integer.parseInt(paramMap.get("age"));
Member member = new Member(username, age);
memberRepository.save(member);
model.put("member", member);
return "save-result";
}
}
V4의 경우 modelView를 반환하지 않고, 단순히 view파일 이름을 반환하고, model은 파라미터 간접참조를 통해 전달한다.
두 종류의 컨트롤러는 다른 형태를 갖지만 동일한 역할을 하고 있는데, 상황에 따라 모두 쓰고싶다면?
-> 어뎁터 패턴을 적용한다.
public interface MyHandlerAdapter {
boolean supports(Object handler);
ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException;
}
supports()로 해당 요청을 처리할 수 있는지 확인한 후, handle()을 호출해 버전에 따라 로직을 수행하도록 한다.
@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<>();
@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);
}
}
요청이 들어왔을 때 처리 로직
1. getHandler()로 해당 URL에 매핑된 핸들러(컨트롤러)를 가져온다.
2. getHandlerAdapter()로 1번에서 가져온 핸들러를 처리할 수 있는 핸들러어뎁터를 가져온다.
3. 2번에서 가져온 어뎁터 핸들러의 handle()을 호출해 로직을 수행하고 ModelView를 리턴한다.
4. viewresolver로 논리적 파일이름에서 절대경로를 가져오고 렌더링을 수행한다.