Servlet Front-Controller에서 하위 컨트롤러 처리하기

Front-Controller

mvc1편에서 배운 Front-Controller v5는, map에 uri를 등록하고, 찾아서 쓰도록 설계 되어 있다.

...

/* handler(Controller)가 매핑된 Map */
private final Map<String, Controller> handlerMappingMap = new HashMap<>();

...

/**
 * 이 클래스가 생성되면서 handler(Controller)가 매핑된 Map, handlerAdapter가 들어있는 List가 초기화 됩니다.
 */
public FrontControllerServlet() {
    initHandlerMappingMap();
}

...

private void initHandlerMappingMap() {
    handlerMappingMap.put("/site", new IndexController());
    handlerMappingMap.put("/site/join", new JoinController());
    handlerMappingMap.put("/site/login", new LoginController());
    handlerMappingMap.put("/site/book/rent", new RentController());
    handlerMappingMap.put("/site/book/unrent", new UnRentController());
    handlerMappingMap.put("/site/admin", new AdminPageController());
    handlerMappingMap.put("/site/users/1", new AdminUsersController1());
    handlerMappingMap.put("/site/users/2", new AdminUsersController2());
    handlerMappingMap.put("/site/users/3", new AdminUsersController3());
    ...
}

...

/* 핸들러 획득 */
Controller handler = getHandler(request);

...

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

단순히 로그인, 회원가입같은 구조는 괜찮지만, REST API 설계를 하기에는 매우 부적합하다. 리소스 위치마다 모두 handlerMappingMap에 등록해줄 수 없기 때문이다.

...

handlerMappingMap.put("/site/users/*", new AdminUsersController());

...

이런 식으로 등록할 수 있다면 참 좋은데, getHandler에서 URI자체를 가져오기 때문에 쉽지 않았다.

해결 방법

해결 방법은 의외로 간단했다. getHandler 메서드에서 핸들러를 찾기에 실패했을 경우 한 번 조건문으로 걸러서 추가해주면 된다. startWith 메서드를 활용했다.

이 방법으로 추가로, /book/rent, /book/unRent까지 개선이 가능할 것 같다.

private void initHandlerMappingMap() {
    ...
    handlerMappingMap.put("/site/users/*", new AdminUsersController());
}

private Controller getHandler(HttpServletRequest request) {
    String requestURI = request.getRequestURI();
    Controller handler = handlerMappingMap.get(requestURI);

    if (handler == null) {
        //users 컨트롤러
        if (request.getRequestURI().startsWith("/site/users/")) {
            handler = handlerMappingMap.get("/site/users/*");
        }
    }

    return handler;
}

댓글

개발자  김철준

백엔드 개발자 김철준의 블로그입니다.

주요 프로젝트