Spring - Interceptor

Interceptor 란 ?

image
출처 : 갓대희의 작은 공간

Interceptor는 Filter와 유사한 형태로 존재한다. AOP가 흩어진 관심사를 묶어 처리하는 것과 같이 공통처리를 위해 활용될 수 있다.

실행순서는 아래와 같다.

요청 : Filter -> Dispatcher Servlet -> Interceptor -> AOP

응답 : AOP -> Interceptor -> Dispatcher Servlet -> Filter


비고 Filter Interceptor
등록 WebApplication(web.xml) Spring Context
전,후처리 chain.doFilter() preHandle, postHandle 등
예외처리 WebApplication ExceptionHandler
기타 Servlet 응답, 요청에 대한 교체 가능 HandlerMethod를 통한 추가 작업, View 렌더링 전 추가 작업, AOP와 유사한 기능 제공(인증단계, 로깅 등), Service business logic과의 분리
사용 인코딩처리, XSS 방어 등 로그인, 권한 체크, 로그확인 등

Interceptor 구현

절차

1. Interceptor를 생성할 때 HandlerInterceptor 인터페이스를 implements 해준다.

2. Spring이 Component Scan을 할 때 인식되기 위해 @Component Annotation을 추가해준다.

3. 전, 후처리에 맞추어 method를 override해준다.

  • 전처리 : preHandle()
  • 후처리 : postHandle()
  • 응답완료 후 : afterCompletion()

아래 예제에서는 전처리를 하기위해 preHandle()메서드를 override 해주었다.

request한 uri와 Auth라는 Annotation을 유무 여부를 체크 및 로깅해주고, Annotation이 있다면 query를 log로 찍어주었다.

CheckAnnotation 메서드는 handler와 handlerMethod를 통해 annotation이 Bean 혹은 MethodAnnotation이 맞는지 체크해주었다.

  • if (handlerMethod instanceof HttpRequestHandler) { return true; } 코드는 Html 등 resource일 시 true를 반환해주도록했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

String uri = request.getRequestURI();
log.info("uri : {}", uri);

URI urii = UriComponentsBuilder.fromUriString(uri)
.query(request.getQueryString())
.build()
.toUri();

boolean hasAnnotation = checkAnnotation(handler, Auth.class);
log.info("has annotation : {}", hasAnnotation);


if (hasAnnotation) {
String query = urii.getQuery();
log.info("query : {}", query);
if (query.equals("name=Inwoo")) {
return true;
}
throw new AuthException();
}

return false;
}

public boolean checkAnnotation(Object handler, Class clazz) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
// pass resource
if (handlerMethod instanceof HttpRequestHandler) {
return true;
}
// pass annotation
if (handlerMethod.getBeanType().getAnnotation(clazz) != null || handlerMethod.getMethodAnnotation(clazz) != null) {
return true;
}

return false;
}
}
Author

Inwoo Jeong

Posted on

2021-10-28

Updated on

2021-10-28

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.

댓글