HandlerAdapter

wangjh789·2022년 8월 2일
0

[Spring] 스프링-mvc-1

목록 보기
7/15

ControllerV3, ContrllerV5 비교

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은 파라미터 간접참조를 통해 전달한다.

두 종류의 컨트롤러는 다른 형태를 갖지만 동일한 역할을 하고 있는데, 상황에 따라 모두 쓰고싶다면?
-> 어뎁터 패턴을 적용한다.

HandlerAdapter 인터페이스

public interface MyHandlerAdapter {
    boolean supports(Object handler);

    ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException;
}

supports()로 해당 요청을 처리할 수 있는지 확인한 후, handle()을 호출해 버전에 따라 로직을 수행하도록 한다.

어뎁터를 적용한 Version5

@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로 논리적 파일이름에서 절대경로를 가져오고 렌더링을 수행한다.

profile
기록

0개의 댓글