요청경로마다 접근제어를 다르게 해야하고 사용자가 특정 URL을 요청할 때마다 내역을 기록하고 싶다면 여러가지 방법이 있을 수 있다. AOP를 사용한다거나 interceptor 두가지 방법이 있는데 AOP는 너무 범용적인 방법이기 때문에 스프링 MVC가 제공하는 HandlerInterceptor를 사용하는 것이 좋다. HandlerInterceptor를 사용하면 다음의 세가지 시점에 공통기능을 적용할 수 있다.
- 컨트롤러(핸들러) 실행 전 - preHandler
- 컨트롤러(핸들러) 실행 후 - postHandler
- 뷰를 실행한 이후 - afterCompletion
1. preHandler
- preHander()메서드를 사용하면 컨트롤러/핸들러 객체를 실행하기 전에 공통기능을 구현할 수 있다. 주로 접근권한이 없을 때 컨트롤러 자체를 실행시키지 않을 대 사용한다. preHandler()메서드의 리턴타입은 boolean으로 false를 리턴하면 컨트롤러(또는 다음 HandlerInterceptor)를 실행하지 않는다.
2. postHandler
- 컨트롤러가 정상적으로 실행 된 이후에 추가적인 기능을 구현할 때 사용되는 메서드이다. 컨트롤러가 익셉션을 발생시키면 실행되지 않는다.
3. afterCompletion
- afterCompletion()메서드는 클라이언트에 뷰를 전송한 뒤에 실행되는 메서드로, 컨트롤러가 익셉션을 발생시키면 동작하지 않는다. 만약 익셉션이 발생하면 이 메서드의 네번째 파라미터로 전달되고, 익셉션이 없으면 네번째 파라미터는 null이 된다. 주로 컨트롤러 실행 중 발생한 익셉션에 대한 로그를 남긴다거나, 메서드 실행시간을 기록하는 등의 처리를 할 때 주로 사용된다.
※ HandlerInterceptorAdapter
- HandlerInterceptor 인터페이스의 모든 메서드를 사용할 일이 없다면 HandlerInterceptorAdapter클래스를 상속받아서 메서드를 재정의한 뒤 사용하면 된다.
- Interceptor클래스를 만든 후 xml설정에서 다음과 같이 적용한다.
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path = "/**"/>
<bean class = "interceptorClass"/>
</mvc:interceptor>
</mvc:interceptors>
만약 여러개의 인터셉터를 순서를 지정해서 정해놓고 싶으면 다음과 같이 지정한다.
Interceptor1, Interceptor2, Interceptor3가 있다고 가정하자. Interceptor1은 /a/**경로에, Interceptor2는 모든경로, Interceptor3는 /b/**, /c/**경로에 지정하려고한다.
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path = "/a/**"/>
<bean class = "interceptor1"/>
</mvc:interceptor>
<bean class = "interceptor2"/>
<mvc:interceptor>
<mvc:mapping path = "/b/**/>
<mvc:mapping path = "/c/**/>
<bean class = "interceptor3"/>
</mvc:interceptor>
</mvc:interceptors>
이것처럼 순서대로 지정하면된다. 메서드의 실행순서는 preHandler()는 지정한 순서대로실행되고, postHandler()와 afterCompletion()메서드는 역순으로 실행된다.
'Spring' 카테고리의 다른 글
Spring(9) - View구현 (0) | 2019.04.15 |
---|---|
Spring(8) - HandlerMapping, HandlerAdapter (0) | 2019.04.15 |
Spring(6) - 스프링 MVC프로젝트 (0) | 2019.04.12 |
Spring(5) - AOP(관점지향프로그래밍) (0) | 2019.04.10 |
Spring(4) - 빈의 생명주기와 범위 (0) | 2019.04.10 |