반응형
가끔 요구사항을 따라 Controller에서 반환된 값에 어떠한 공통된 데이터를 삽입해야하거나 로깅을 해야할 수도 있다.이를 위해서 다양한 방법이 있겠지만 그중에서 Interceptor를 사용할 수 있다.
Interceptor...?
Spring MVC 프레임워크에서 HTTP 요청을 가로채어 처리하는 컴포넌트를 의미한다. 클라이언트의 요청이 Controller에 도달하기 전 또는 처리된 후 추가적인 작업을 처리할 수 있다.
서버에 들어온 Request를 Controller의 Handler로 넘겨주기 전, 후에 낚아채어 개발자가 원하는 작업을 수행할 수 있도록 하는 것이 Interceptor이다.
특징
전역적 처리
- 여러 컨트롤러에서 나눠서 처리되어야 하는 작업을 중앙에서 관리할 수 있으며 인증, 권한 검사, 로깅 등 전역적인 작업을 Interceptor에 위임할 수 있다.
- 코드의 중복을 줄이고 유지보수성을 향상할 수 있다.
요청 처리 제어
- Controller에 요청이 도달하기 전, 처리가 완료된 후 작동하여 Request의 전처리또는 후처리를 제어할 수 있다.
설정의 유연함
- XML, Annotation 등의 설정 방식을 이용하여 Interceptor를 등록하고 관리할 수 있다.
- 개발자의 선호나 프로젝트의 요구사항에 맞추어 자유롭게 설정할 수 있다.
다중 Interceptor
- 여러 개의 Interceptor를 배치하여 일종의 Interceptor Chain을 구성할 수 있다.
- 이를 활용하여 각각의 Interceptor가 처리한 결과를 조합하여 최종 처리 결과를 도출할 수 있다.
동작과정
- HandlerMapping 검색 - HandlerMapping 컴포넌트가 요청 URL과 관련된 적절한 Controller를 탐색한다.
- Interceptor Chain 생성 - 해당 Controller와 연결된 여러 Interceptor 객체들로 구성된 Chain를 구성한다.
- PreHandler 메서드 호출 - Interceptor Chain의 각 Interceptor은 PreHandler 메서드를 호출하여 요청을 가로채어 요청을 처리하기 전 전처리를 수행할 수 있다.
- Controller 호출 - PreHandler 실행 후 HandlerMapping가 적절한 Controller를 선택하여 호출한다.
- PostHandler 메서드 호출 - Controller의 실행이 완료된 후 각 Interceptor의 PostHandler 메서드가 호출되며 Controller의 반환값을 가로채고 후처리를 수행할 수 있다.
- View 렌더링과 응답 - PostHandler 메서드 실행 후 적절한 View를 렌더링 하여 클라이언트에 반환한다.
- AfterCompletion 메서드 호출 - 응답 이후 각 Interception의 AfterCompletion 메서드가 실행되며 주로 리소스 정리나 로깅을 실행할 수 있다.
더보기
비동기 요청에선 postHandler가 실행되지 않을 수 있다
Filter와 AOP
특징 | Interceptor | Filter | AOP |
---|---|---|---|
동작 위치 | Spring MVC 레벨 (DispatcherServlet 이후) | Servlet 레벨 (DispatcherServlet 이전) | Spring Bean 메서드 호출 전후 |
목적 | 컨트롤러 호출 전후의 작업 (인증, 로깅, 전처리 등) | HTTP 요청 및 응답 처리 (헤더 조작, 필터링 등) | 메서드 실행 전후 또는 특정 지점에서의 부가 작업 |
적용 대상 | Spring MVC 요청 흐름에 한정 | 웹 애플리케이션의 모든 HTTP 요청/응답 | 모든 Spring Bean (특정 메서드, 클래스 등) |
등록 방식 | WebMvcConfigurer 의 addInterceptors 로 등록 |
@Bean 으로 Filter 등록 또는 web.xml 설정 |
@Aspect 와 Pointcut 표현식으로 정의 |
Spring 의존성 | Spring MVC에 의존 | Spring 없이도 사용 가능 (Servlet 스펙 기반) | Spring AOP에 의존 |
주요 메서드 | preHandle , postHandle , afterCompletion |
doFilter |
@Before , @After , @Around |
적용 범위 | 컨트롤러 메서드 호출 전/후, View 렌더링 전후 | HTTP 요청/응답의 원시 데이터를 조작 | 특정 메서드나 클래스에서 공통 로직 실행 |
요청 흐름 관여 정도 | 요청 흐름을 가로채거나, 추가 작업을 삽입 | 요청 흐름의 전반적 제어 가능 (헤더, 바디, 응답 등) | 메서드 수준에서만 동작 |
사용 사례 | 인증, 인가, 로깅, 요청 전처리/후처리 | CORS 처리, 응답 압축, 인증 토큰 검증 | 트랜잭션 관리, 로깅, 예외 처리 |
View와의 연관성 | View 렌더링 전/후에 추가 작업 가능 | View와 직접 연관되지 않음 | View와 직접 연관되지 않음 |
활용 예시 | 공통 데이터 삽입,로깅,API 호출 제한 등 | CORS 처리,인증 토큰 검증 등 | 공통 관심사(로깅, 트랜젝션 관리 등)를 처리 |
- 특히나 Filter는 HTTP 요청/응답 레벨에서 동작하고, Interceptor는 컨트롤러 전후로 동작한다.
구현
HandlerInterceptor 인터페이스를 구현하여 사용한다 .
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class CustomInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("[preHandle] 컨트롤러 실행 전");
return true; // false 반환 시 작동 중단
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("[postHandle] 컨트롤러 실행 후");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("[afterCompletion] View 렌더링 후");
}
}
WebMvcConfigurer 인터페이스를 구현한 설정 클래스를 이용하여 Spring MVC에 등록한다.
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
private final CustomInterceptor customInterceptor;
public WebConfig(CustomInterceptor customInterceptor) {
this.customInterceptor = customInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(customInterceptor)
.addPathPatterns("/api/**") // 적용할 경로
.excludePathPatterns("/api/login", "/api/register"); // 제외할 경로
}
}
'Springboot' 카테고리의 다른 글
Whitelabel Error Page와 Tomcat Error Page (0) | 2025.04.26 |
---|---|
[Spring] Spring Batch (0) | 2025.03.05 |
[Spring] Spring Cloud (1) | 2025.02.05 |
[Spring] Thread Pool과 Spring Scheduler (1) | 2024.12.30 |