Deep Dive /Java Web /17-V2

17-V2. DispatcherServlet → HandlerInterceptor: postHandle()

뷰 렌더링 경로에서는 컨트롤러 호출이 끝난 뒤 postHandle()이 실행됩니다. 이 호출은 DispatcherServlet.doDispatch()HandlerExecutionChain.applyPostHandle()에서 확인할 수 있습니다.


이번 단계의 역할

컨트롤러 결과를 뷰 렌더링 전에 한 번 더 가공하거나 로깅할 수 있는 후처리 단계입니다.


호출 흐름 요약

  1. DispatcherServletHandlerAdapter.handle(...)를 마칩니다.
  2. mappedHandler.applyPostHandle(...)를 호출합니다.
  3. HandlerExecutionChain이 등록된 인터셉터를 역순으로 순회합니다.
  4. 각 인터셉터의 postHandle()이 실행됩니다.

호출 흐름 다이어그램

sequenceDiagram participant DS as DispatcherServlet participant Chain as HandlerExecutionChain participant I2 as Interceptor N participant I1 as Interceptor 1 DS->>Chain: applyPostHandle(request, response, mv) Chain->>I2: postHandle(...) Chain->>I1: postHandle(...)

핵심 코드

// DispatcherServlet.java
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
// HandlerExecutionChain.java
void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
        throws Exception {
    for (int i = this.interceptorList.size() - 1; i >= 0; i--) {
        HandlerInterceptor interceptor = this.interceptorList.get(i);
        interceptor.postHandle(request, response, this.handler, mv);
    }
}

코드 해설

postHandle()은 컨트롤러가 성공적으로 끝난 뒤, 실제 뷰를 그리기 직전에 실행됩니다. 그래서 모델 보강, 공통 속성 추가, 로깅 같은 작업을 하기에 적합합니다.


설계 의도

컨트롤러 본문과 뷰 렌더링 사이에 확장 포인트를 두기 위해 존재하는 단계입니다.


다음 단계 연결

다음 문서 17-V3에서는 DispatcherServlet이 뷰 이름으로부터 ViewResolver를 통해 실제 View 객체를 찾는 과정을 봅니다.

← 이전: 17-V1. Controller → DispatcherServlet: ModelAndView 반환 | 다음: 17-V3. DispatcherServlet → ViewResolver