Filter란?
Spring Boot에서 Filter는 HTTP 요청(Request)과 응답(Response)을 가장 앞단에서 가로채는 컴포넌트이다.
조금 더 정확히 말하면 Filter는 Servlet 스펙(Servlet Specification) 에 속하며, Spring MVC 이전 단계에서 동작하며 DispatcherServlet이 요청을 받기 이전에 실행된다. 요청 흐름을 간단히 표현하면 다음과 같다.
Client
↓
Filter (Servlet Filter)
↓
DispatcherServlet
↓
Interceptor
↓
Controller
이 구조 때문에 Filter는 다음과 같은 특징을 가진다.
- 모든 HTTP 요청에 대해 공통적으로 동작 가능
- Controller 여부와 상관없이 실행됨
- Request / Response 원본 객체에 접근 가능
왜 Filter가 필요한가?
웹 애플리케이션을 개발하다 보면, 모든 요청에 대해 공통적으로 처리해야 하는 로직이 반드시 생긴다.
예를 들면 다음과 같은 것들이다.
- 인증 / 인가 처리 (JWT, 세션 검사 등)
- 요청/응답 로깅
- XSS / SQL Injection 방어
- Request Body 캐싱
- 공통 헤더 처리 (CORS, Security Header 등)
이런 로직을 Controller마다 작성한다면?
- 중복 코드 증가
- 유지보수 난이도 상승
Filter는 이런 문제를 해결하기 위해 요청의 진입 지점에서 한 번에 처리할 수 있도록 해준다.
Filter의 핵심 특징
1. 실행 시점
Filter는 DispatcherServlet 이전에 실행된다.
즉, 다음과 같은 정보만 존재한다.
- URL
- HTTP Method
- Header
- Body (직접 읽어야 함)
아직 Controller, HandlerMethod, @RequestParam 같은 Spring MVC 정보는 없다.
2. Request / Response 원본 객체
Filter에서는 다음 객체를 직접 다룬다.
- HttpServletRequest
- HttpServletResponse
이 객체들은 아직 가공되지 않은 원본 객체이기 때문에, 한 번 읽으면 다시 읽을 수 없다는 특징이 있다.
그래서 Request Body를 여러 번 사용하려면 Request Wrapping이 필요하다.
3. Spring Bean 접근
Filter는 Servlet 스펙 기반이기 때문에, 기본적으로는 Spring Bean 접근이 제한적이다.
하지만 Spring Boot에서는 다음 방식으로 해결한다.
- @Component
- FilterRegistrationBean
이를 통해 Spring Bean 주입도 가능하다.
Filter 사용 방법
1. Filter 구현
@Component
public class SampleFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 요청 전 처리
System.out.println("Filter Before: " + req.getRequestURI());
chain.doFilter(request, response);
// 응답 후 처리
System.out.println("Filter After");
}
}
chain.doFilter()를 기준으로 나뉜다.
- 이전: 요청 처리
- 이후: 응답 처리
2. Filter 등록 및 순서 지정
@Bean
public FilterRegistrationBean<SampleFilter> sampleFilter() {
FilterRegistrationBean<SampleFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new SampleFilter());
bean.addUrlPatterns("/*");
bean.setOrder(1);
return bean;
}
- addUrlPatterns : 적용 URL
- setOrder : Filter 실행 순서 (숫자가 작을수록 먼저 실행)
나는 Filter를 어떻게 사용했는가
나는 Spring Boot 기반의 백엔드 프로젝트에서 Filter를 다음과 같은 용도로 사용했다.
1. 보안 목적 Filter
- XSS 방어를 위한 Request Body Sanitizing
- Header 기반 공격 방어
- 특정 HTTP Method 제한
Controller에 도달하기 전 입력값 자체를 정제하는 역할로 사용했다.
2. Request Body 캐싱
Spring에서는 Request Body를 한 번 읽으면 다시 읽을 수 없다. 하지만 다음과 같은 경우에는 여러 번 필요하다.
- Filter에서 로깅
- Controller에서 실제 처리
이를 해결하기 위해 HttpServletRequestWrapper를 사용해 Body를 캐싱했다.
3. 공통 로깅 처리
- 요청 URL
- HTTP Method
- 요청 시간
- 응답 상태 코드
을 Filter에서 공통으로 로깅하여 Controller 코드를 깔끔하게 유지했다.
Filter의 한계
Filter는 강력하지만 한계도 명확하다.
- Spring MVC 정보 접근 불가
- Handler, Controller 정보 모름
- 예외 처리 제어가 어려움
이 때문에 다음과 같은 경우에는 다른 기술이 더 적합하다.
- Controller 기준의 인증/인가 → Interceptor
- 비즈니스 로직 공통 처리 → AOP
다음 글에서는 다음 내용을 다룰 예정이다.
- Filter vs Interceptor vs AOP
- 실행 시점 차이
- 사용 목적별 선택 기준
- 실제 프로젝트에서의 역할 분리 전략
언제 Filter를 쓰고, 언제 Interceptor나 AOP를 써야 하는지를 정리해볼 예정이다.
마무리하자면,
Filter는 요청/응답 데이터를 필터링하고, 흐름을 제어하며, 공통적인 사전/사후 작업을 수행
Spring Boot 웹 애플리케이션에서 공통 관심사를 가장 앞단에서 처리하고 싶다면, Filter는 가장 먼저 고려해야 할 도구이다.
'Web-BE > Spring' 카테고리의 다른 글
| 스프링 AOP(Spring AOP) 제대로 이해하기 (0) | 2025.12.18 |
|---|