Spring에서 인터셉터 적용하기

2019. 1. 3. 17:53 Spring Framework/Spring Core

해당 포스팅에서는 Spring Interceptor에 관하여 알아보고 적용을 하는 포스팅이다.

실제 프로젝트 적용 및 예제는 다음 포스팅에서 할 예정이다.


1. Java 인터셉터 구현 

- 인터셉터로 사용할 클래스를 하나 만들어준다. 

- 형태는 아래와 같다.


import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;


public class ExamInterceptor extends HandlerInterceptorAdapter {

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handle) throws Exception {

return true;

}


@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,

ModelAndView modelAndView) throws Exception {

super.postHandle(request, response, handler, modelAndView);

}

}


HandlerInterceptorAdapter 를 상속 받아서 구현을 한다. 

구현되는 메서드는 아래와 같다. 


preHandle

- Controller 실행 요청 전에 수행되는 메서드

- 클라이언트의 요청을 컨트롤러에 전달 하기 전에 호출

- return 값으로 boolean 값을 전달하는데 false 인 경우 controller를 실행 시키지 않고 요청 종료

- 보통 이곳에서 체크작업을 진행한다. (구현자의 취향대로 적용해도 된다.)


postHandle

- view(JSP, timeleaf) 단으로 forward 되기 전에 수행

- 컨트롤러 로직이 실행된 이후 호출

- 컨트롤러 단에서 에러 발생 시 해당 메서드는 수행되지 않는다. 

- request로 넘어온 데이터 가공 시 많이 사용된다.


구현 내용을 보다시피 preHandle에서 로그인 및 url 접근 시 체크를 많이 진행하게 된다. 

위 클래스를 구현한다 해도 인터셉터는 작동하지 않는다. 

다음의 설정 작업을 진행하도록 하자.


2. XML에서 인터셉터 설정

프로젝트 구성 및 설정 xml에 따라 다르겠지만 대부분 servlet-context.xml에서 설정한다.

설정 코드는 아래를 참고하자.


<beans:bean id="interceptorForExam" class="com.exam.ExamInterceptor">

</beans:bean>

<mvc:interceptors>

<mvc:interceptor>

<mvc:mapping path="/*" />

<mvc:exclude-mapping path="/login/**" />

<mvc:exclude-mapping path="/add/**" />

<beans:ref bean="interceptorForExam" />

</mvc:interceptor>

</mvc:interceptors>


위의 설정 코드를 설명하면 다음과 같다. 


- 첫 번째 라인은 인터셉터 클래스의 빈(Bean)을 등록하는 과정이다.

  아까 작성한 클래스로 빈을 등록한다.

- 두 번째 라인은 인터셉터 선언부를 나타낸다. 

  인터셉터는 여기에서 설정을 하게 되며, 1개 이상의 인터셉터 설정을 작성한다.

- 세 번째 라인은 인터셉터 설정을 나타내는 부분으로써 여기에서 적용할 Url, 적용할 인터셉터 빈, 

  예외처리 등을 구성한다.

- 네 번째 라인은 인터셉터를 적용할 Url을 설정한다.

  컨트롤러에서 @RequestMapping으로 설정한 URL을 이곳에 작성할 경우 해당 인터셉터를 타게 

  된다는 뜻이다. 

  /* 적용을 하게 되면 현재 프로젝트의 모든 URL에 적용을 한다는 뜻이며, /someproject/login/* 이라

  작성할 경우 /someproject의 /login/* 의 URL로 접근하는 경우 해당 인터셉터를 타게 된다는 뜻이다. 

- 다섯 번째 라인은 예외를 둔다는 것이다. 

  예를 들어 로그인 페이지가 /login/login 인데 매핑한 경로가 /login/* 일 경우 무한 리다이렉션이

  발생하게 된다. (왜 발생하는지는 for(int i=0; i<2; i)  라 적은 구문과 비슷하다 해야 할까나?)

  이런 현상을 막기 위해 특별하게 인터셉터 적용을 하지 않을 URL은 이렇게 예외를 적용하면 된다.

  또한 추가적으로 예외를 두려면 다음 라인과 같이 적용하면 된다.

- 일곱 번째 라인은 해당 인터셉터를 처리할 빈을 적용하는 부분이다. 


위와 같이 적용 후 톰캣 등에 올려서 실행을 해볼 경우 인터셉터의 동작을 확인할 수 있다.


출처: http://elfinlas.tistory.com/343 [MHLab Blog]