AbstractController

상속 구조
사용자 삽입 이미지하는 일
모든 컨트롤러들의 기본이 되는 클래스로써 위 그림에 표시되어 있는 일들을 합니다.
여기서 한 가지 주목할 것은 Controller 인터페이스를 구현함에 따라 구현해야할 handleRequest 입니다.
이 메소드는 final로 다음과 같이 구현되어 있습니다.

    public final ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        // Delegate to WebContentGenerator for checking and preparing.
        checkAndPrepare(request, response, this instanceof LastModified);

        // Execute handleRequestInternal in synchronized block if required.
        if (this.synchronizeOnSession) {
            HttpSession session = request.getSession(false);
            if (session != null) {
                Object mutex = WebUtils.getSessionMutex(session);
                synchronized (mutex) {
                    return handleRequestInternal(request, response);
                }
            }
        }
       
        return handleRequestInternal(request, response);
    }

이 메소드와 관련된 자세한 설명은 KSUG 제 2회 세미나에서 영회형이 설명해주셨지만 Spring MVC 118쪽에도 적혀있습니다. 워크 플로우와 메소드들의 라이프 사이클을 지키면서도 상속 받아 사용하는 녀석들에 때라 행동을 다르게 정의 할 수 있도록 Open-Closed Principle 을 구현한 사례에 해당합니다.

Workflow
1. DispatcherServelet에 의해 handleRequest() 호출됨.
2. 지원하는 요청의 타입을 조사(만약 지원하는 요청이 아닐 경우 ServletException 발생)
3. 세션이 필오하면 가져오려고 시도함.(없을 경우 ServletException 발생)
4. cacheSeconds 속성에 따라 필요하다면 캐슁 헤더를 설정함.
5. handleRequestInternal() 추상 메소드를 호출(이때 설정에 따라 HttpSession을 동기화 함)

13.3.1. AbstractController and WebContentGenerator

다양한 컨트롤러들의 가장 기반이 되는 구현체인 AbstractController에서 설정할 수 있는 속성들은 다음과 같습니다.

Feature

Explanation

supportedMethods

어떤 형식의 요청을 받아 들일지 설정합니다. 보통은 GET 이나 POST 둘 중 하나며 원하는 메서드 이름으로 바꿀
수 도 있습니다. 지원 하지 않는 요청의 경우
ServletException
이 발생합니다.

requiresSession

해당 컨트롤러가 작업을
할 때 Http session이 필요한지 설정합니다.

만약 필요로 하는데도 session을 담고 있는 request가 오지 않으면 SevletException이 발생합니다.

synchronizeSession

사용자의 Session을 동기화 처리해주고 싶을 때 사용합니다.

cacheSeconds

이 컨트롤러가 Http reponse에 캐쉬를 남기고 싶을 때 사용합니다.

기본값은 -1로 캐쉬를 남기지 않습니다.

useExpiresHeader

생성할 response
HTTP 1.0
과 호환 가능한 “Expires” 헤더를 기술합니다.

기본값은 true입니다.

useCacheHeader

생성할 responseHTTP 1.1과 호환 가능한 “Cache-Control” 헤더를 기술합니다.

기본값은 true입니다.

AbstractController를 사용하는 방법은 간단합니다. 다음과 같이 handleRequest 메소드를 구현해주면 됩니다.

package samples;

public class SampleController extends AbstractController {

    public ModelAndView handleRequestInternal(
        HttpServletRequest request,
        HttpServletResponse response) throws Exception {

        ModelAndView mav = new ModelAndView(“hello”);
        mav.addObject(“message”, “Hello World!”);
        return mav;       
    }
}

AbstractController와 Controller 간의 관계는 다음과 같습니다.
사용자 삽입 이미지
이 컨트롤러는 view 이름을 소스 코드 내부에 위치 해야 하는 단점이 있습니다. 이렇게 되면 view가 바뀔 때 마다 소스 코드를 수정해줘야 하죠.