실무에서 개발을 진행하다가 클라이언트의 요청 로그를 Controller 호출 전에 찍는 코드를 보게 되었다. 인터셉터를 사용하였는데, 인터셉터에 대한 기본 지식이 없어서 제대로 코드를 이해하진 못했지만 때마침 인프런 강의에서 인터셉터와 필터 원리 및 구현 방법에 대해서 설명하여 잊지 않기 위해 기록해본다,,,!!
인터셉터는 추후에 정리해서 올릴예정,,,!!!
서블릿이 지원하는 필터이다.
HTTP 요청 -> WAS -> 필터 -> 서블릿(스프링일 경우 디스패처 서블릿) -> 컨트롤러
public interface Filter {
public default void init(FilterConfig filterConfig) throws ServletException
{}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
public default void destroy() {}
}
init() - 필터 초기화 담당, 서블릿 컨테이너가 생성될 때 호출
dofilter() -> 클라이언트의 요청 시 호출 되는 메서드, 보통 여기에서 구현
destroy() -> 필터 종료 메서드, 서블릿 컨테이너가 종료 될 때 호출
@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 {
log.info("log filter doFilter");
// 1. HttpServletRequest 로 다운 캐스팅
HttpServletRequest httpRequest = (HttpServletRequest) request;
// 2. 필터가 수행 할 로직
String uuid = UUID.randomUUID().toString();
String requestUri = httpRequest.getRequestURI();
try {
log.info("REQUEST [{}] [{}] ", uuid, requestUri);
// 3. 필터가 수행 된 후에는 서블릿을 호출 할 수 있게 해야하기 때문에
// dofilter 로 서블릿 호출
chain.doFilter(request, response);
} catch (Exception e) {
throw e;
}finally {
log.info("RESPONSE [{}] [{}]", uuid, requestUri);
}
}
@Override
public void destroy() {
log.info("log filter destroy");
}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public FilterRegistrationBean logFilter() {
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new LogFilter());
filterRegistrationBean.setOrder(1);
filterRegistrationBean.addUrlPatterns("/*");
return filterRegistrationBean;
}