Dev/Spring

Spring[Interceptor-Annotation활용]

OK-가자 2021. 10. 16. 22:42

Spring[Interceptor-Annotation활용]

1. 인터셉터란?

  • Spring에서 HTTP Request와 HTTP Response를 Controller 앞과 뒤에서 가로채는 역할을 한다.
  • Servlet의 앞과 뒤에서 HTTP Request와 HTTP Response를 가로채는 필터와 유사 하다.
  • Interceptor를 구현하기 위해서는 HandlerInterceptor 인터페이스를 구현하여야 한다.
  • 서블릿 필터와 차이

자료 001

2. 구현실습

  • 1) MyInterceptor 구현
    HandlerInterceptor 인터페이스의 3개의 메소드를 구현한다.
    1. preHandle() 메소드는 컨트롤러가 호출되기 전에 실행된다. handler 파라미터는 HandlerMapping 이 찾아준 컨트롤러의 메소드를 참조할 수 있는 HandlerMethod 오브젝트이다. 반환값이 true이면 핸들러의 다음 체인이 실행되지만 false이면 중단하고 남은 인터셉터와 컨트롤러가 실행되지 않는다.
    2. postHandle() 메소드는 컨트롤러가 실행된 후에 호출된다.
    3. afterComplete() 은 뷰에서 최종결과가 생성하는 일을 포함한 모든 일이 완료 되었을 때 실행된다.
  • 2) 등록 ( spring-servlet.xml )
  • <!-- Interceptors --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/board/**" /> <bean class="com.bit2015.mysite3.interceptor.MyInterceptor" /> </mvc:interceptor> </mvc:interceptors>
    핸들러 인터셉터는 하나 이상 등록할 수 있으며 등록 순서대로 preHandle()이 실행된다.
    postHandle()과 afterComplete()은 그 반대로 실행된다.

- 3) 테스트 하기
    1. mapping path 변경 하기
    2. mapping path 여러 개 추가해 보기
    3. MyInterceptor 의 preHandle 리턴 값 변경 해보기 

- 4) HandlerInterceptorAdapter 추상 클래스를 상속하여 구현 할 수 있다.
    HandlerInterceptorAdapter는 HandleInterceptor 인터페이스 기본 메소드를 구현하여 놓았기 때문에  상속한  인터셉터가 필요한  메소드만  오버라이딩하여  다시 구현하면 된다.

    HandlerInterceptorAdapter를  상속하여 MyInterceptor2 작성한 후, 설정하고  로그 를 확인한다. 
## 3. AuthInterceptor 구현하기
- 1) 인증 여부에  따른  특정 URL 접근 제한
- 2)  /user/login  URL 처리
      Interceptor 에서는  ApplicationContext 를 구해서  직접  저장된 빈을 가져와야 한다.

ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext( request.getServletContext() );
UserService userService = applicationContext.getBean( UserService.class );

- 3) /user/logout URL 처리  

## 4. Annotation의 활용
- Annotation 이란?
    1. Java5부터 지원
    2. Class, Method, Parameter에 메타정보를  삽입한다.
    3. 컴파일 할 때, 또는 실행시  해당타켓에  코드를 추가적으로 실행할 수 있게 한다.
    4. 코드의 가독성을 향상시키고 체계적인 코드를 구성할 수 있다.

@Auth
@RequestMapping( "/modifyform" )
public String modifyForm( @AuthUser UserVo authUser, Model model ) {

}

  5. 정의

@Target( ElemenType.METHOD )
@Retention( RetentionPolicy.RUNTIME )
public @interface Auth {

}


    @Target :  어노테이션의 타켓을 지정 ( FIELD, METHOD, PARAMETER, TYPE)
    @Retention: 어노테이션의 지속 (보존) 기간을 지정(  RUNTIME, SOURCE )  

-  인터셉터의 PATH mapping을  Handler 어노테이션으로 대체하는 실습
    1. 접근제한에 해당하는 URL로 매핑된 메서드에  @Auth를 추가한다. 
    2. AuthInteceptor에 다음 코드를 추가한다.

Auth auth = ( ( HandlerMethod ) handler ).getMethodAnnotation( Auth.class );
if( auth == null ) {
return true;
}

   3. Interceptor 설정을 변경한다.

mvc:interceptor
<mvc:mapping path="/" />
<mvc:exclude-mapping path="/user/login" />
<mvc:exclude-mapping path="/assets/
" />


-  @AuthUser 적용하기
    1. 어노테이션  정의 

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthUser {
}

   2. HandlerMethodArgumentResolver 인터페이스 구현

public class AuthUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
if( this.supportsParameter(parameter) == false ) {
return WebArgumentResolver.UNRESOLVED;
}

HttpServletRequest httpServletRequest = 
           webRequest. getNativeRequest( HttpServletRequest.class );
HttpSession session = httpServletRequest.getSession();

UserVo authUser = (UserVo) session.getAttribute( "authUser" );
return authUser;

}

@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterAnnotation( AuthUser.class ) != null &&
parameter.getParameterType().equals( UserVo.class );
}
}

   3. AuthUserHandlerMethodArgumentResolver 등록

mvc:annotation-driven

mvc:argument-resolvers


```

'Dev > Spring' 카테고리의 다른 글

Spring[Logging]  (0) 2021.10.17
Spring[MultipartResolver]  (0) 2021.10.16
Spring [DefaultServlet-ViewResolver-Exception]  (0) 2021.10.16
Spring @MVC, Data Access, MyBatis  (0) 2021.10.15
Spring[Message-Converter]  (0) 2021.10.15