DispatcherServlet과 컨트롤러 사이에 위치하며 컨트롤러에 요청이 들어가기 전에 가로채 특정 작업을 하거나 컨트롤러에서 요청에 대한 작업이 끝나고 응답할 때 추가적인 작업을 하는 것을 말한다. 그렇기에 로깅 또는 인증/인가와 같은 공통 작업을 처리하기위해 많이 사용한다.

실습 환경
- Spring Boot 2.6.0
- Java 11
깃허브 링크 : 클릭
인터셉터 구현
servlet 패키지의 HandlerInterceptor interface를 구현하여 인터셉터를 구현할 수 있다.
@Slf4j
public class FirstFilter implements Filter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("First Interceptor preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("First Interceptor postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
- preHandle : 컨트롤러가 호출되기 전 실행
- postHandle : 컨트롤러 작업이 완료된 후 실행
- afterCompletion : 뷰에서 최종 결과를 렌더링한 후에 실행
인터셉터 등록
설정 파일을 만들어 빈으로 등록한다.
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new FirstInterceptor())
.order(1)
.addPathPatterns("/*")
.excludePathPatterns("/second-interceptor");
}
}
- order : 인터셉터 실행 우선순위를 결정한다. 낮을 수록 높은 우선순위를 가진다.
- addPathPatterns : 인터셉터를 적용시킬 url 등록
- excludePathPatterns : 제외할 url 등록
테스트
컨트롤러를 등록하고 테스트 코드를 작성해서 확인해보자
Controller
@RestController
@Slf4j
public class HelloController {
@GetMapping("/")
public String hello() {
log.info("/ 진입");
return "Hello";
}
}
Test Code
@SpringBootTest
@AutoConfigureMockMvc
class HelloControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void enter_root() throws Exception {
//when, then
mockMvc.perform(MockMvcRequestBuilders.get("/"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
결과

심화
컨트롤러, 인터셉터를 두 개씩 더 추가해서 테스트해보자
Interceptor
@Slf4j
public class SecondInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("Second Interceptor preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("Second Interceptor postHandle");
}
}
@Slf4j
public class ThirdInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("Third Interceptor preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("Third Interceptor postHandle");
}
}
Bean Regist
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new FirstInterceptor())
...;
/* 추가 */
registry.addInterceptor(new SecondInterceptor())
.order(0)
.addPathPatterns("/", "/second-interceptor");
registry.addInterceptor(new ThirdInterceptor())
.order(2)
.addPathPatterns("/**")
.excludePathPatterns("/second-interceptor");
}
}
Controller
@GetMapping("/second-interceptor")
public String hello2() {
log.info("/second-interceptor 진입");
return "Hello";
}
@GetMapping("/third/interceptor")
public String hello3() {
log.info("/third-interceptor 진입");
return "Hello";
}
Test Code
@SpringBootTest
@AutoConfigureMockMvc
class HelloControllerTest {
@Autowired
MockMvc mockMvc;
@Test
public void enter_root() throws Exception {
//when, then
mockMvc.perform(MockMvcRequestBuilders.get("/"))
.andExpect(MockMvcResultMatchers.status().isOk());
mockMvc.perform(MockMvcRequestBuilders.get("/second-interceptor"))
.andExpect(MockMvcResultMatchers.status().isOk());
mockMvc.perform(MockMvcRequestBuilders.get("/third/interceptor"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
}
표 정리
| - | first | second | third |
|---|---|---|---|
| 우선순위 | 1 | 0 | 2 |
| url patterns | /* | /, /second-interceptor | /** |
| exclude patterns | /second-interceptor | - | /second-interceptor |
결과

- / 진입
- 세 개의 인터셉터를 보면 /*, /, /**를 포함하고 있기 때문에 전부 실행되는데 이때 우선순위가 second > first > third 이기 때문에 순서대로 실행된다.
- /second-interceptor 진입
- first, third 인터셉터는 exclude url에 /second-interceptor가 포함되어 있기 때문에 second 인터셉터만 접근한다.
- /third/interceptor
- /** 가지는 third 인터셉터만 접근이 가능하다.
/*, /** 차이
- /* : / 다음에 오는 모든 문자열을 포함하는 경로를 말함
- /** : / 를 포함하는 모든 문자열과 그 아래 하위 모든 경로도 포함함