Java : Servlet필터 사용하기

NuyHes·2025년 8월 8일
0

[Study]

목록 보기
63/71
post-thumbnail

🕵️ 서블릿 필터(Filter)란?

필터Java 웹 어플리케이션에서 클라이언트 요청(Request)과 서블릿/리소스 처리 그리고 응답(Response) 사이에 끼어들어 공통 작업을 처리할 수 있는 기능이다.

필터가 할 수 있는 대표적인 일

  • 요청/응답 인코딩 처리 (UTF-8)
  • 인증/인가 처리
  • 로깅/모니터링
  • 압축, 이미지 변환 등 데이터 가공

구조

[클라이언트] 👉 (Filter) 👉 [서블릿/JSP] 👉 (Filter) 👉 [클라이언트]


필터 생명주기 & 스레드 안전성

컨테이너 시작 시 한번 생성 👉 여러 요청을 다중 스레드로 처리

생명 주기 메서드

  • init(FilterConfig config) : 초기화 (초기 파라미터 읽기 등)
  • doFilter(ServletRequest, ServletResponse, FilterChain) : 전/후처리
  • destory() : 종료 정리

패키지 생성

package com.example.test.filter;  
  
import javax.servlet.*;  
import java.io.IOException;  
  
public class CharacterEncodingFilter implements Filter {  
        @Override  
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)  
		throws IOException, SecurityException, ServletException {  
            req.setCharacterEncoding("UTF-8");  
            chain.doFilter(req, resp);  
        }  
}

해당 패키지에 filter를 추가한 패키지를 만들고 클래스를 생성한다.


실행 순서

  • web.xml에서 선언한 <filter-mapping> 순서대로 실행
<filter-mapping>  
    <filter-name>Filter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>
	...
<filter-mapping>  
    ...
</filter-mapping>
	...
	...
  • 어노테이션(@WebFilter)만 쓰면 순서는 컨테이너 구현에 의존할 수 있음 -> 순서가 중요하면 web.xml에 명시

매핑 방법

  • URL 패턴 : /* , /api/* , *.jsp
  • 디스패처 타입 (기본 : REQUEST) : REQUEST , FORWARD , INCLUDE , ERROR , ASYNC ( 예 : 에러 페이지에도 적용하려면 ERROR 추가)

많이 쓰이는 패턴 예제

1) 인코딩 필터 (전처리만)

public class CharacterEncodingFilter implements Filter {
  @Override
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
      throws IOException, ServletException {
    req.setCharacterEncoding("UTF-8");   // getParameter 호출보다 먼저!
    chain.doFilter(req, resp);
  }
}

2) 로깅/타이밍 필터 (전 후처리)

public class LoggingFilter implements Filter {
  @Override
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
      throws IOException, ServletException {
    long start = System.currentTimeMillis();
    try {
      chain.doFilter(req, resp); // 다음 단계로
    } finally {
      long took = System.currentTimeMillis() - start;
      System.out.println("Request took " + took + "ms");
    }
  }
}

try/finally후처리 보장


3) 인증 필터 (짧게 차단하기)

public class AuthFilter implements Filter {
  @Override
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
      throws IOException, ServletException {
    var httpReq = (javax.servlet.http.HttpServletRequest) req;
    var httpResp = (javax.servlet.http.HttpServletResponse) resp;

    boolean ok = httpReq.getSession(false) != null;
    if (!ok) {
      httpResp.sendError(401); // 또는 redirect
      return;                  // 체인 중단
    }
    chain.doFilter(req, resp);
  }
}

설정 방법

web.xml 방법 (명시적, 순서 제어 용이)

<filter>
  <filter-name>CharacterEncodingFilter</filter-name>
  <filter-class>com.example.test.filter.CharacterEncodingFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>CharacterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
</filter-mapping>
  • 여러 필터가 있으면 <filter-mapping> 순서가 실행 순서
  • 환경별 설정 분리, 팀 협업, 세밀한 순서 제어에 유리

어노테이션 (@WebFilter 방법)

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(
  urlPatterns = "/*",
  dispatcherTypes = { DispatcherType.REQUEST, DispatcherType.ERROR }  // 필요 시
  // asyncSupported = true
)
public class CharacterEncodingFilter implements Filter {
  @Override
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
      throws IOException, ServletException {
    req.setCharacterEncoding("UTF-8");
    chain.doFilter(req, resp);
  }
}
  • 장점 : XML없이 한 파일에 정의 (빠르고 직관적)
  • 주의 : 필터 순서 보장 어려움 (정밀한 순서 제어 필요하면 web.xml 추천)

0개의 댓글