클라이언트 요청이 들어왔을때 컨트롤러마다 기능 로직을 수행 하기 전 요청을 가로채는 역할.
ex) 비로그인 유저가 로그인 유저만 접속할 수 있는 특정 페이지를 url만 복사해서 접속 했다고 가정 했을때 별도의 처리가 안되어있다면 비로그인유저도 사용 가능할것이다.
이를 방지 하기 위해 인터셉터에 로직을 추가하여 요청들을 컨트롤러가 처리하기 전에 가로채 로직을 끼워 넣는다. 호출 시점은 Dispatcher Servlet이 실행 된 후 실행된다.
servlet.xml
<!-- servlet.xml -->
<interceptors>
<interceptor>
<!-- 모든 url적용 -->
<mapping path="/*" />
<!-- 예외처리 -->
<exclude-mapping path="/main"/>
<!-- 적용interceptor -->
<beans:bean id="testInterceptor" class="com.main.test.interceptor.TestInterceptor" />
</interceptor>
</interceptors>
preHandle() 메서드는 컨트롤러 호출 전에 실행.
postHandle() 메서드는 컨트롤러 호출 후에 실행
afterComplete() 메서드는 컨트롤러 호출 후 뷰에서 최종 결과까지 완료 된 후 실행.
각 메서드의 return 값이 true면 핸들러의 다음 체인이 실행.
false면 중단하고 남은 인터셉터와 컨트롤러가 실행 .
public class MyInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler){
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler, ModelAndView modelAndView){
}
@Override afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex){
}
}
상속 받으면 메서드가 구현되어 있으므로 필요한 메서드만 오버라이딩 하면 된다.
public class TestInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
return true;
}
@Override
public void postHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
@Nullable ModelAndView modelAndView) throws Exception{
}
@Override
public void afterCompletion(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
@Nullable Exception ex) throws Exception{
}
@Override
public void afterConcurrentHandlingStarted(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
}
}
호출시점은 Dispatcher Servlet 실행 전에 실행하여 요청 내용을 변경하거나 체크할 수 있다.
또한 응답내용에 대해서도 변경을 수행할 수 있다. 보통 web.xml에 등록, 인코딩 변환과 XSS방어등의 요청에 대한 처리로 사용된다.
init() 메서드는 필터 인스턴스를 초기화.
doFilter() 메서드는 전/후 처리.
destroy() 메서드는 필터 인스턴스 종료.
관점 지향 프로그래밍
인터셉터와 필터랑은 달리 메서드 전후의 지점에서 자유롭게 설정이 가능.
주로 로깅, 트렌젝션, 에러 처리등 비즈니스 메서드에서 디테일한 조정이 필요할때 사용.
@After는 대상 메서드의 수행 후 실행
@Before는 대상 메서드의 수행 전 실행
@Around 대상 메서드의 수행 전/후 실행