Servlet Filter, interceptor 차이
Servlet 실행 전, 후에 어떤 작업을 하고자 할 때 Servelt Filter를 사용한다.

서블릿 필터 정의 : Dispatcher Servlet에 요청이 전달되기 전, 후에 부가작업을 처리하는 객체
@Component : 모든 url 패턴에 대해 적용되버림 .
@WebFilter 어노테이션을 달면 특정 url 패턴에 대해서만 필터를 적용하게 할 수 있다. 다만 순서를 지정할 수가 없다.
FilterRegistrationBean으로 적용
setFitler, setOrder,addUrlPattern 등으로 부가 설정을 가장 많이 할 수 있다.


스프링 인터셉터 인터페이스





핸들러 어댑터 종류?
## 1. 어노테이션 기반 컨트롤러 (Annotation-driven Controller)
오늘날 스프링 MVC의 표준이자 가장 널리 사용되는 방식입니다. @Controller 또는 @RestController 어노테이션을 클래스에 붙이고, @RequestMapping (또는 @GetMapping, @PostMapping 등)을 메서드에 붙여 요청을 처리합니다.
특징: 매우 유연하고 직관적입니다. 파라미터나 반환 타입을 자유롭게 사용할 수 있습니다 (
@RequestParam,@RequestBody,String,ResponseEntity등).코드 예시:
Java
처리 어댑터:
RequestMappingHandlerAdapter
## 2. Controller 인터페이스 구현체
Controller 인터페이스 구현체스프링 초창기부터 사용된 가장 전통적인 방식입니다. org.springframework.web.servlet.mvc.Controller 인터페이스를 직접 구현해야 합니다.
특징:
handleRequest라는 단 하나의 메서드만 구현하면 되므로 구조가 매우 단순합니다. 다만, 반환 타입이ModelAndView로 고정되어 있어 유연성이 떨어집니다.코드 예시:
Java
처리 어댑터:
SimpleControllerHandlerAdapter
## 3. 함수형 핸들러 (Functional Handler)
Spring 5부터 도입된 방식으로, 람다식을 사용하여 요청과 응답을 함수(Function)로 정의합니다. 어노테이션 없이 코드로 직접 라우팅 규칙을 설정합니다.
특징: 매우 간결하며, 컴파일 시점에 타입 체크가 가능합니다. 함수형 프로그래밍에 익숙하다면 강력한 방식입니다. 주로
RouterFunction과HandlerFunction을 조합하여 사용합니다.코드 예시:
Java
처리 어댑터:
HandlerFunctionAdapter


모든 인터셉터 성공적으로 실행 완료 되면?


postHandle에 등록된 역순으로 인터셉터가 실행된다.


view 관련 로직까지 완료가 된 후에
이제 스프링 인터셉터 AfterCompletion 메서드가 실행된다.



## 1. @ControllerAdvice: 컨트롤러를 위한 전역 보좌관 👨⚕️
@ControllerAdvice: 컨트롤러를 위한 전역 보좌관 👨⚕️@ControllerAdvice는 모든 @Controller 또는 특정 패키지의 컨트롤러에 대해 전역적으로 적용되는 로직을 정의할 때 사용합니다. 주로 다음과 같은 세 가지 목적으로 쓰입니다.
전역 예외 처리 (
@ExceptionHandler): 여러 컨트롤러에서 발생할 수 있는 특정 예외(e.g.,IllegalArgumentException)를 한 곳에서 잡아 공통된 에러 응답(JSON 또는 에러 페이지)을 보내줍니다. 이것이 가장 핵심적인 용도입니다.Java
공통 모델 데이터 추가 (
@ModelAttribute): 모든 뷰(View)에 공통으로 필요한 모델 데이터(e.g., 현재 로그인 사용자 정보)를 자동으로 추가해 줍니다.데이터 바인딩 설정 (
@InitBinder): 모든 컨트롤러에 적용될 커스텀 데이터 바인딩 규칙을 정의합니다.
@ControllerAdvice는 DispatcherServlet이 컨트롤러를 실행하는 과정에서 발생하는 특정 상황(예외 등)에 개입하는 특수 부대와 같습니다.
## 2. 요청/응답(Request/Response)을 바꾸는 경우
요청과 응답을 중간에 변경하는 작업은 주로 **필터(Filter)**의 역할입니다. 필터는 DispatcherServlet에 요청이 전달되기 전, 가장 바깥단에서 동작하여 원본 요청과 응답에 직접 관여하기 때문입니다.
Request를 바꾸는 경우
문자 인코딩 설정: 모든 요청의 인코딩을 UTF-8로 강제하는
CharacterEncodingFilter.요청 본문 재사용: 로깅 등의 목적으로 요청 본문을 여러 번 읽을 수 있도록
ContentCachingRequestWrapper로 감싸는 경우.인증 정보 추가: 커스텀 헤더에 담긴 인증 정보를 파싱하여
HttpServletRequest에 속성으로 추가하는 경우.
Response를 바꾸는 경우
공통 헤더 추가: 모든 응답에 CORS 관련 헤더나 보안 관련 헤더(
X-XSS-Protection등)를 추가하는 경우.응답 데이터 압축: 응답 본문을 Gzip으로 압축하여 전송량을 줄이는 경우.
## 3. 필터(Filter) vs 인터셉터(Interceptor) 핵심 차이
이것이 질문의 핵심입니다. 둘 다 요청을 가로채지만, 실행되는 위치와 권한이 다릅니다.
### 비유: 건물 출입 🏢
필터 (Filter): 건물 정문에 있는 1차 보안요원.
위치: 건물(웹 컨테이너)의 가장 바깥쪽.
역할: 건물에 들어오는 모든 방문객(모든 요청)을 가장 먼저 확인. 인코딩, 보안 등 애플리케이션과 무관한 저수준의 처리를 담당.
특징: 회사 내부 사정(스프링 컨테이너)은 모름.
Service같은 스프링 Bean을 주입받을 수 없음.
인터셉터 (Interceptor): 특정 사무실(스프링 MVC) 입구의 2차 안내데스크 직원.
위치: 정문을 통과한 후, 실제 사무실(컨트롤러)로 들어가기 직전.
역할: 해당 사무실의 규칙에 따라 방문객의 출입을 제어. 로그인 여부, 관리자 권한 확인 등 비즈니스 로직과 관련된 처리를 담당.
특징: 회사 내부 사정(스프링 컨테이너)을 잘 앎.
@Service등 필요한 Bean을 주입받아 복잡한 로직 수행 가능.
### 비교표
실행 시점
DispatcherServlet 전/후
DispatcherServlet 후, Controller 전/후
관리 주체
서블릿 컨테이너 (Tomcat)
스프링 컨테이너 (IoC)
접근 정보
ServletRequest, ServletResponse (원본 요청)
HttpServletRequest, HttpServletResponse, 컨트롤러 정보(HandlerMethod), ModelAndView
DI 가능 여부
원칙적으론 불가 (단, DelegatingFilterProxy로 우회)
가능 (@Autowired 등)
주요 사용처
인코딩, 보안 초기화(Spring Security), CORS, 로깅
로그인/권한 체크, 로깅(사용자 정보 포함), 공통 데이터 추가
### 실행 흐름도
Request → [Filter] → [DispatcherServlet] → [Interceptor (preHandle)] → [Controller] → [Interceptor (postHandle)] → [View] → [Interceptor (afterCompletion)] → [DispatcherServlet] → [Filter] → Response
관심사 분리라고 생각.
스프링 시큐리티 활용해서 로그인 구현해도 사실 인터셉터처럼 스프링 컨테이너의 빈들을 활용할 수 있기 때문에
스프링 시큐리티는 필터의 강력한 요청 가로채기 능력과 인터셉터의 유연한 스프링 Bean 활용 능력이라는 두 가지 장점을 모두 취한 매우 영리한 설계를 가지고 있습니다. 따라서 로그인이나 인가 처리를 할 때 DB 접근, 다른 서비스 로직 호출 등 정교한 작업이 모두 가능한 것입니다.
Last updated