인터셉터 구현

dongeranguk·2021년 10월 6일

스프링은 이미 AOP를 제공하고 있지만, AOP는 너무 범용적인 방법이다.

스프링 MVC는 여러 컨트롤러에 공통으로 적용되는 기능을 구현하는 방법인 HandlerInterceptor를 제공하고 있으며, 공통 기능을 다수의 URL에 적용할 수 있게 된다.

1. HandlerInterceptor 인터페이스 구현하기

org.springframework.web.servlet.HandlerInterceptor 인터페이스를 사용하면, 다음의 세가지 시점에 대해 공통 기능을 넣을 수 있다.

  • 컨트롤러(핸들러)실행 전
  • 컨트롤러(핸들러)실행 후, 아직 뷰를 실행하기 전
  • 뷰를 실행한 이후

세 시점을 처리하기 위해 HandlerInterceptor 인터페이스는 다음과 같이 세 개의 메서드를 정의하고 있다.

package org.springframework.web.servlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.method.HandlerMethod;

public interface HandlerInterceptor {
	boolean preHandle(HttpServletRequest request,
    	HttpServletResponse response, Object Handler) throws Exception;
        
   	void postHandle(HttpServletRequest request,
    	HttpServletResponse response, Object handler, 
    	ModelAndView modelAndView) throws Exception;
        
 	void afterCompletion(
    HttpServletRequest request, HttpServletResponse response, Object handler,
    Exception ex) throws Exception;

1.1. preHandle 메서드

preHandle() 메서드는 컨트롤러/핸들러 객체를 실행하기 전에 필요한 기능을 구현할 때 사용된다. handler 파라미터는 웹 요청을 처리할 컨트롤러/핸들러 객체이다.

이 메서드를 사용하면 접근 권한이 없는 경우 컨트롤러를 실행하지 않는다거나, 컨트롤러를 실행하기 전에 컨트롤러에서 필요로 하는 정보를 생성하는 등의 작업이 가능하다.

1.2. postHandle 메서드

postHandle() 메서드는 컨트롤러/핸들러 객체가 정상적으로 실행된 이후에 추가 기능을 구현할 때 사용된다. 만약 컨트롤러가 예외를 발생하면 postHandle() 메서드는 실행되지 않는다.

1.3. afterCompletion 메서드

afterCompletion() 메서드는 클라이언트에 뷰를 전송한 뒤에 실행된다.

만약 컨트롤러를 실행하는 과정에서 예외가 발생하면,
이 메서드의 네 번째 파라미터(Exception ex)로 전달된다.
예외가 발생하지 않았다면 네 번째 파라미터는 null이 된다.

따라서, 컨트롤러 실행 이후 발생한 예외를 로그로 남긴다거나, 실행 시간을 기록하는 등의 후처리를 하기에 적합한 메서드이다.


2. HandlerInterceptorAdapter 클래스

HandlerInterceptorAdapter 클래스는 HandlerInterceptor 인터페이스를 구현하고 있는데 각 메서드는 아무 기능도 수행하지 않는다.

따라서, HandlerInterceptor 인터페이스의 메서드를 모두 구현할 필요가 없다면, HandlerInterceptorAdapter 클래스를 상속받은 뒤 필요한 메서드만 재정의하면 된다.


3. HandlerInterceptor 설정하기

HandlerInterceptor를 구현했다면, 웹 요청을 처리할 때 HandlerInterceptor가 적용되도록 설정에 추가하는 것이다. 추가하는 방법은 다음과 같다.

<mvc:interceptors>
	<bean id="exerciseInterceptor"
            class="com.spring.exercise.ExerciseInterceptor" />
</mvc:interceptors>

<mvc:interceptors> 태그는 HandlerInterceptor 설정과 경로 설정을 함께 설정할 때 사용된다.

위 설정의 경우 <mvc:interceptors> 태그 내부에 빈 객체를 HandlerInterceptor로 사용하고, DispatcherServlet이 처리하는 모든 요청에 대해 HandlerInterceptor를 적용하게 된다.

만약, 특정 요청 경로에 대해서만 HandlerInterceptor를 적용하고 싶다면 아래과 같이 중첩된 <mvc:interceptor> 태그를 사용한다.

<mvc:interceptors>
	<mvc:interceptor>
          <mvc:mapping path="/event/**" />
          <mvc:mapping path="/folders/**" />
          <bean class="com.spring.exercise.ExerciseInterceptor"/>
      	</mvc:interceptor>
</mvc:interceptors>

위 설정에서 <mvc:mapping>은 HandlerInterceptor를 적용할 요청 경로 패턴을 지정한다. (이 경로는 컨텍스트 경로를 제외한 나머지 경로와 매핑된다.)

<mvc:mapping> 태그로 지정한 경로 패턴에 적용될 HandlerInterceptor 는 < bean>태그를 이용해서 지정한다.


(출처: 웹 개발자를 위한 Spring 4.0 프로그래밍, 저자 : 최범균)

0개의 댓글