TIL

2024.05.27.월 스프링 필터

Nellucia 2024. 5. 28. 14:10
스프링 필터


Filter : 
스프링 필터는 HTTP 요청과 응답을 가로채고 처리하는 기능을 제공하는 서버 측 컴포넌트

 

 

스프링 프레임워크(Spring Framework)에서 필터(Filter)는 HTTP 요청과 응답을 가로채고 처리하는 데 사용되는 중요한 구성 요소이다. 필터는 요청이 서블릿(Servlet)이나 컨트롤러에 도달하기 전 또는 응답이 클라이언트에게 반환되기 전에 특정 작업을 수행할 수 있도록 한다.

주로 범용적으로 처리해야 하는 작업들, 예를들어 로깅 및 보안 처리에 활용하며 인증, 인가와 관련된 로직들을 처리할 수도 있다.Filter를 사용하면 인증, 인가와 관련된 로직을 비즈니스 로직과 분리하여 관리할 수 있다는 장점이 있다.

 

 

  1. 요청 및 응답 처리: 필터는 클라이언트의 요청을 가로채서 처리하거나 변환할 수 있으며, 응답도 마찬가지로 수정할 수 있다.
  2. 체인 형태로 구성: 여러 필터를 체인(chain) 형태로 구성하여 순차적으로 실행할 수 있다. 각 필터는 다음 필터로 제어를 넘기거나 처리 중단을 선택할 수 있다.
  3. 사전 및 사후 처리: 요청이 서블릿에 도달하기 전에 사전 처리(pre-processing)를 수행하고, 응답이 클라이언트에게 반환되기 전에 사후 처리(post-processing)를 수행할 수 있다..

 

 

Filter Interface

package jakarta.servlet;

import java.io.IOException;

public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    default void destroy() {
    }
}

 

  • init(): 필터가 초기화될 때 호출 (서블릿이 필터를 등록하는 초기화 과정)
  • doFilter(): 필터의 핵심 메서드로, 요청과 응답을 처리하는 로직을 작성 
    • 요청, 응답, FilterChain 객체에 접근 할 수 있음.
    • FilterChain 객체는 다음 필터를 호출
  • destroy(): 필터가 종료될 때 호출 (서블릿 컨테이너가 필터를 제거할 때)

 

Filter Chain

 

필터 체인은 말그대로 연쇄적으로 거쳐서 흘러가게 드는 역할

Filter는 한 개만 존재하는 것이 아니라 이렇게 여러 개가 Chain 형식으로 묶여서 처리될 수 있다.

 

 

 

필터는 자신의 작업이 완료되면 FilterChain 을 호출해서 요청이 다음 필터를 통과하게 만들다.

  • 단일 책임 원칙
  • 책임 연쇄 패턴

 

 

Filter 등록

 

@Component 어노테이션을 사용하여 필터를 빈으로 등록하거나 "FilterRegistrationBean"을 사용하여 명시적으로 등록할 수 있다.

@WebFilter 어노테이션과 @ServletComponentScan을 사용하는 방법도 있다.

 

 

1.@Component

  • 설정을 위한 별개의 파일이 필요하지 않는다.
  • @Order 애노테이션을 이용해 순서를 설정할 수 있다.
  • 기본 URL Pattern이 /* 이며 설정할 수 없다.
@Slf4j
@Component // 추가된 두 가지
@Order(1)  // 추가된 두 가지 
public class LoggingFilter implements Filter {

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
      FilterChain filterChain) throws IOException, ServletException {
    // 전처리
    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    String url = httpServletRequest.getRequestURI();
    log.info(url);

    filterChain.doFilter(servletRequest, servletResponse); // 다음 Filter 로 이동
  }
}

 

 

2. FilterRegistrationBean ( @Configuration)

 

@Congiguration어노테이션은 클래스가 하나 이상의 @Bean 메서드를 선언하고 스프링 IoC 컨테이너에서 빈 정의를 생성하고 제공하는 데 사용된다. 간단히 말해, @Configuration이 붙은 클래스는 스프링의 설정 파일 역할을 하며, 애플리케이션 컨텍스트를 구성하는데 사용되는 것이다.

필터 등록을 위해 FilterRegistrationBean을 스프링 컨텍스트에서 이 클래스를 인식하고 빈으로 등록하기만 하면 되므로 스프링 부트 애플리케이션 클래스에 직접 FilterRegistrationBean을 등록할 수도 있다. 하지만 보통 @Configuration어노테이션과 함께 사용한다.

 

  • 설정을 위한 별개의 파일(@Configuration 이 붙은 객체)이 필요하다. 
  • setOrder() 를 통해 순서를 정할 수 있다.
  • addUrlPatterns() 을 통해 베이스 URL 및 Whitelist를 설정할 수 있다.
  • @Congiguration 어노테이션은 FilterRegistrationBean 을 사용항
@Configuration
public class FilterConfiguration {

  /**
   * 로그 관련 필터 추가.
   *
   * @return
   */
  @Bean
  public FilterRegistrationBean loggingFilter() {
    FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
    filterRegistrationBean.setFilter(new LoggingFilter());
    filterRegistrationBean.setOrder(1);
    filterRegistrationBean.addUrlPatterns("/*");

    return filterRegistrationBean;
  }
}

 

 

3. @WebFilter + @ServletComponentScan

  • 설정을 위한 별개의 파일이 필요하지 않는다.
    • 대신, 애플리케이션 실행되는 메인 객체위에 @ServletComponentScan 을 사용해야 한다.
  • @Order를 이용한 순서 등록을 사용할 수 없다. (각 필터에 대한 순서를 보장할 수 없다.)
  • @WebFilter 의 value 나 urlPatterns 파라미터를 이용해 whitelist 방식으로 베이스 URL을 설정할 수 있다.
    • @WebFilter("/filter/*")
    • @WebFilter({"/login", "/items"})
    • @WebFilter(urlPatterns = "/filter/*")
    • @WebFilter(urlPatterns = {"/login", "/items"})

 

@Slf4j
@WebFilter
public class LoggingFilter implements Filter {

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
      FilterChain filterChain) throws IOException, ServletException {
    // 전처리
    HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
    String url = httpServletRequest.getRequestURI();
    log.info(url);

    filterChain.doFilter(servletRequest, servletResponse); // 다음 Filter 로 이동
  }
}

 

@ServletComponentScan
@SpringBootApplication
public class FilterPatternApplication {

  /**
   * main.
   *
   * @param args argument.
   */
  public static void main(String[] args) {
    SpringApplication.run(FilterPatternApplication.class, args);
  }

}

 

 

  장점 단점
@Component 간단한 설정
자동 컴포넌트 스캔
일관된 스프링 관리
세밀한 설정 어려움
조건부 등록 번거로움
FilterRegistrationBean 세밀한 설정 가능
조건부 등록 가능
프로그램적 제어 가능
설정이 다소 복잡
설정 클래스와 필터 구현 클래스의 분리
@WebFilter+@ServletComponentScan 서블릿 표준 준수
어노테이션 기반 설정
자동 스캔
설정의 명확성
스프링 관리(다른 빈들과 동일한 방식으로 관리되지 않을 수 있다)
특정 패키지 제한(패키지 구조 주의)

 

 

 

스프링 필터는 웹 애플리케이션에서 요청과 응답을 가로채고 처리하는 강력한 도구이다. 필터는 사전 및 사후 처리를 수행할 수 있으며, 여러 필터를 체인 형태로 구성하여 다양한 작업을 처리할 수 있다. 필터를 등록하는 데에는 여러 방법이 있지만  프로젝트의 구조와 관리 방식에 맞게 선택해야 한다.

 

 

 

 

 

 

 

'TIL' 카테고리의 다른 글

2024.05.29.수 영속성 전이  (0) 2024.05.30
2024.05.28.화 RestTemplate & Open API  (0) 2024.05.30
2024.05.24.금  (0) 2024.05.28
2024.05.23.목  (1) 2024.05.24
2024.05.22.수 Bean  (1) 2024.05.23