인터셉터 구현

dongeranguk·2021년 10월 6일
0

스프링은 이미 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개의 댓글