Contents
서블릿 필터를 이용해 로그 처리
   May 2, 2023     3 min read

서블릿 필터 - 요청 로그

⚓️서블릿 필터을 이용해 모든 요청에 로그를 남길 수 있다. 만들어보자.


➡️서블릿 필터 - 요청 로그

  • LogFilter - 로그 필터
import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.UUID;

@Slf4j
public class LogFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("log filter init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String requestURI = httpRequest.getRequestURI();

        String uuid = UUID.randomUUID().toString();

        try {

        } catch (Exception e){
            throw e;
        } finally{
            log.info("RESPONSE [{}] [{}]", uuid, requestURI);
        }
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
  1. 필터를 사용하려면 인터페이스 Filter를 구현한다.
  2. 구현해야하는 것은 init(), doFilter(), destory() 세 가지 이다.
  3. 각자 제대로 동작하는지 log를 넣어보자.
  4. doFilter는 HTTP 요청이 오면 doFilter가 호출된다.
  5. HttpServletRequest httpRequest는 HTTP 요청이 아닌 경우까지 고려해서 만든 인터페이스다. HTTP를 사용하면 다운 캐스팅을 통해서 사용 하면된다. → (HttpServletRequest) request;
  6. uuid 는 HTTP 요청을 구별하기 위해서 요청당 임의의 UUID를 생성한다.
  7. log.info(”REQUEST [{ }] [{ }]”, uuid, requestURI); → UUID와 reqeustURI를 출력

🚨중요🚨 - chain.doFilter(requst, response);

  • 다음 필터가 있으면 다음 필터를 호출하고, 필터가 없을 경우 서블릿을 호출한다. 이 로직을 호출하지 않는다면 다음 단계로 진행되지 않는다.

➡️WebConfig

-

import hello.login.web.filter.LogFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;

@Configuration
public class WebConfig {

    @Bean
    public FilterRegistrationBean logFilter(){
        FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new LogFilter());
        filterRegistrationBean.setOrder(1);
        filterRegistrationBean.addUrlPatterns("/*");

        return filterRegistrationBean;
    }
}

✅서블릿 필터

➡️필터 흐름

HTTP 요청 → WAS(Tomcat) → filter → Servlet → Controller

필터를 적용하면 필터가 호출 된 다음에 서블릿이 호출된다.

  • 스프링의 경우 : Servlet → DispatcherServlet
HTTP 요청 → WAS(Tomcat) → filter → DispatcherServlet → Controller

➡️필터의 활용

  • 요청 로그 기록 남기기
  • 로그인 여부 체크

➡️필터 체인

HTTP 요청 -> WAS(Tomcat) -> 필터1 -> 필터2 -> 필터3 -> 서블릿 -> 컨트롤러

필터는 체인으로 구성되는데, 중간에 필터를 자유롭게 추가 할 수 있다.

➡️필터의 생명주기

  • init() : 필터 초기화 메서드, 서블릿 컨테이너가 생성될 때 호출된다.
  • doFilter() : 고객의 요청이 올 때 마다 해당 메서드가 호출된다. 필터의 로직을 구현하면 된다.
  • destroy() : 필터 종료 메서드, 서블릿 컨테이너가 종료될 때 호출된다.

📎출처


필터를 등록하는 방법은 많지만, 스프링 부트를 사용한다면 FilterRegistrationBean 을 사용해서 등록하면 됨.

  • filterRegistrationBean.setFilter() : 등록할 필터를 지정
  • filterRegistrationBean.setOrder(1) : 필터는 체인으로 동작한다. 따라서 순서가 필요하다. 낮을 수록 먼저 동작.
    • @ServletComponentScan , @WebFilter(filterName = “logFilter”, urlPatterns = “/*” 로 필터 등록이 가능한다, 하지만 필터 순서 조절이 기능이 없다.
  • filterRegistrationBean.addUrlPatterns("/*") : 필터를 적용할 URL 패턴을 지정한다. 한번에 여러 패턴을 지정할 수 있음.

📎참고