인증이 필요한 서비스를 개발할 경우, Interceptor에서 로그인 유무를 확인하는 로직을 추가하여 각 컨트롤러에 인증 로직을 추가로 작성하지 않도록 할수 있습니다.
만약 이때 어떤 컨트롤러의 메소드는 로그인을 체크하고 어떤 컨트롤러의 메소드에는 로그인을 체크하지 않도록 하려면 어떻게 해야 할까요?
스프링 3.2 부터는 mvc:interceptor 부분에 exclude-mapping 이라는 엘리먼트가 추가되어 기존의 스프링 버전보다 쉽게 인터셉터의 적용을 제외시킬수 있습니다.
<mvc:interceptor> <mvc:mapping path="/**"/> <exclude-mapping path="/info/**"/> <bean class="net.krespo.interceptor.LoginCheckInterceptor" /> </mvc:interceptor>
이렇게 exclude-mapping을 사용하면 LoginCheckInterceptor는 /info/ 로 시작하는 컨트롤러에 인터셉터 적용을 제외 시킬수 있습니다.
그런데 만약 /info/my는 로그인 인터셉터를 수행시키고 /info/test는 로그인 인터셉터를 수행시키려면 어떻게 해야할까요?
물론 exclude-mapping을 여러개 등록하면 되지만 로그인이 필요하지 않은 컨트롤러가 생길때마다 exclude-mapping을 선언하는것이 귀찮게 느껴질겁니다.
이럴때는 임의의 어노테이션을 생성하여 인증이 필요하지 않은 컨트롤러의 메소드에 어노테이션을 붙이고, 어노테이션 유무를 인터셉터에서 확인하여 로그인을 할지 안할지를 하면 좀더 편하게 개발을 진행할 수 있을것 같습니다.
이제부터 본격적으로 인터셉터에서 컨트롤러의 어노테이션을 체크하는 방법을 알아보도록 하겠습니다.
1. 어노테이션 생성
package net.krespo.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface NoLoginCheck { }
NoLoginCheck라는 어노테이션을 생성하였습니다. 이 어노테이션을 사용하여 어노테이션을 메소드에 추가를 했으면 로그인 체크를 하고, 어노테이션이 없으면 로그인 체크를 하지 않도록 할것입니다.
2. 컨트롤러에 어노테이션 추가
@Controller public class MyController { @RequestMapping("/my/info") @NoLoginCheck public ModelAndView myInfo(){ ... } }
3. Interceptor에서 어노테이션 체크하기
public class LoginInterceptor extends WebContentInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException { //@NoCheckLogin 어노테이션이 컨트롤러에 사용되었는지 체크함 NoCheckLogin usingAuth = ((HandlerMethod) handler).getMethodAnnotation(NoCheckLogin.class); //NoCheckLogin 어노테이션이 없음으로 무조건 로그인 체크 if(usingAuth == null) { //TODO 로그인 체크 } //NoCheckLogin 어노테이션이 없음으로 로그인 체크 하지 않음 else { //TODO 추가작업 } } }
가장 중요한 부분은 preHandler 메소드의 handler Object를 HandlerMethod로 타입케스팅 하는 부분입니다. 이렇게 HandlerMethod로 바꾼 handler오브젝트의 getMethodAnnotation을 통해서 앞으로 실행될 컨트롤러의 메소드에 해당 어노테이션이 추가가 되었는지 안되어 있는지를 확인할 수 있습니다.
위 내용은 스프링 3.2에서 확인해 보았습니다. 그러나 스프링 3.0에서는 해당 handler Object를 HandlerMethod의 오브젝트가 아닌 앞으로 실행시킬 컨트롤러오브젝트(위의 예제에서는 LoginController)가 반환이 됨으로 위의 코드는 3.0에서는 사용할 수가 없습니다~(3.1에서는 체크를 해보지 못했습니다. 3.1에서 사용해 보신 분께서는 댓글로 알려주세요~^^)
'Framework > SPRING FRAMEWORK' 카테고리의 다른 글
[Spring 3.2] @ControllerAdvice를 이용한 익셉션 처리 (0) | 2013.11.29 |
---|---|
[Spring Framework] @RequestParam을 사용하여 List형 데이터 받을때 주의점 (2) | 2013.11.14 |
[Spring Framework] @Transactional로 구현한 트랜젝션에서 수동 rollback 하기 (5) | 2013.11.14 |
Spring - Spring + iBatis 연동시 iBatis Transaction 실행 안되는 문제 (0) | 2010.12.13 |
Spring - Quartz를 사용하여 스케쥴러 구현하기 (12) | 2010.09.29 |