Filter
Filter는 웹 컴포넌트가 실행되기 전/후에 요청과 응답을 가로채서 부가적인 기능을 수행하기 위한 웹 컴포넌트다.
Filter와 Servlet의 차이점
- Filter: 모든 요청에 대한 공통 처리 (횡단 관심사)
- Servlet: 특정 URL에 대한 비즈니스 로직 처리
- 실행 순서: WAS → Filter Chain → Servlet → Filter Chain → WAS
Filter가 필요한 이유
- 인코딩 처리는 모든 요청에 필요 → 각 Servlet에 반복 코드 방지
- 인증/인가를 중앙에서 통제
- 요청/응답 로깅을 일괄 처리
Filter의 주요 용도
- 인증 및 권한 확인: 사용자가 특정 페이지에 접근하기 전에 로그인 여부와 권한 확인
- 로깅: 어떤 요청이 있었는지, 어떤 응답이 있었는지 추적
- 보안: 요청을 검사하여 악의적인 코드나 공격 차단 (XSS 공격 등)
- 인코딩 설정: 모든 요청/응답에 대한 문자 인코딩 일괄 처리
- CORS 설정: Cross-Origin Resource Sharing 헤더 추가
- 압축: 응답 데이터 압축 (gzip)
Filter 구현 예시
1. 로깅 필터
모든 요청에 대한 로깅을 수행한다.
LoggingFilter.java
@WebFilter(urlPatterns = {"/*"})
public class LoggingFilter extends HttpFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest hreq = (HttpServletRequest) request;
// 1. 요청 정보 로깅
System.out.println(hreq.getRequestURL() + " : " + hreq.getMethod());
// 파라미터 로깅
Map<String, String[]> params = hreq.getParameterMap();
params.forEach((key, values) -> {
for (String value : values) {
System.out.println("Key: " + key + ", Value: " + value);
}
});
// 2. 다음 필터 또는 서블릿 호출
chain.doFilter(request, response);
}
}2. XSS 공격 방지 필터
크로스 사이트 스크립팅(XSS) 공격을 방지한다.
XssFilter.java
@WebFilter(urlPatterns = {"/*"})
public class XssFilter extends HttpFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// XSS 방지를 위한 RequestWrapper 사용
chain.doFilter(new MyXssRequestWrapper((HttpServletRequest) request), response);
}
// RequestWrapper 클래스
class MyXssRequestWrapper extends HttpServletRequestWrapper {
public MyXssRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value != null) {
// HTML 태그를 안전한 문자로 치환
value = value
.replaceAll("<", "<")
.replaceAll(">", ">");
}
return value;
}
}
}Filter Chain
Filter는 체인 형태로 연결되어 순서대로 실행된다. 여러 개의 필터가 연쇄적으로 연결되어 순서대로 실행될 수 있으며, 각 Filter는 chain.doFilter()를 호출해야 다음 처리로 넘어간다.
Filter Chain 동작 흐름
Filter 처리 순서
- 요청 단계: 클라이언트 → Filter 1 → Filter 2 → Filter 3 → Filter 4 → Servlet
- 응답 단계: Servlet → Filter 4 → Filter 3 → Filter 2 → Filter 1 → 클라이언트
각 Filter는 요청/응답을 수정할 수 있으며, 응답은 역방향으로 체인을 통과한다.
Filter 구현 패턴
// Filter의 기본 흐름
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 1. 전처리 (요청이 Servlet으로 가기 전)
// 예: 인코딩 설정, 로깅, 인증 체크 등
// 2. 다음 Filter 또는 Servlet 호출 (필수!)
chain.doFilter(request, response);
// 3. 후처리 (응답이 클라이언트로 가기 전)
// 예: 응답 로깅, 리소스 정리 등
}Filter와 Interceptor의 차이
Filter (Servlet 스펙)
- Container 수준에서 동작
- Servlet이 실행되기 전/후 처리
- web.xml 또는 @WebFilter로 설정
Interceptor (Spring MVC)
- Spring MVC 수준에서 동작
- Handler(Controller) 실행 전/후/완료 시점 처리
- 더 세밀한 제어 가능
정리
- Filter: 모든 요청/응답을 가로채서 공통 처리
- 인증/인가, 로깅, 보안(XSS 방지), 인코딩 등
- chain.doFilter() 호출 필수
- 횡단 관심사를 처리하는 핵심 컴포넌트
Last updated on