티스토리 뷰

 

spring 을 사용할 때 에러가 난다면 아래와 같은 모양으로 호출이 된다.

1. WAS(여기까지 전파) <- 필터 <- 서블릿 <- 인터셉터 <- 컨트롤러(예외발생)
2. WAS `/error-page/500`
다시 요청 -> 필터 -> 서블릿 -> 인터셉터 -> 컨트롤러(/error- page/500) -> View

 

여기서 필터의 경우 2번이나 호출된다. 자원적으로는 낭비이며 굳이 요청할 필요가 없다. 혹은 에러페이지일 때만 요청하는 필터를 필요로 할 수도 있을 것이다.

 

먼저 로그 필터를 만들어 주었다.

 

package hello.exception.filter;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
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 {
            log.info("REQUEST  [{}][{}][{}]", uuid, request.getDispatcherType(), requestURI);
            chain.doFilter(request, response);
        } catch (Exception e) {
            throw e;
        } finally {
            log.info("RESPONSE [{}][{}][{}]", uuid, request.getDispatcherType(), requestURI);
        }

    }

    @Override
    public void destroy() {
        log.info("log filter destroy");
    }
}

 

 

등록을 해줄 것이다.

 

package hello.exception;

import hello.exception.filter.LogFilter;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.Filter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public FilterRegistrationBean logFilter(){
        FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new LogFilter());
        filterRegistrationBean.setOrder(1);
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST,DispatcherType.ERROR); //요청과 에러일 경우에만 호출된다.

        return filterRegistrationBean;
    }

}

 

여기에서 중요한 부분은 

filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST,DispatcherType.ERROR); //요청과 에러일 경우에만 호출된다.

 

해당 부분인데 FilterRegistrationBean으로 필터를 등록할 때에 dispatcher타입을 등록해 줄 수 있다.

 

종류는 다음과 같다.

 

public enum DispatcherType {
      FORWARD,
      INCLUDE,
      REQUEST,
      ASYNC,
      ERROR
}

 

forward는 서블릿을 사용할 때에 다른 맵핑으로 넘겨줄 때에 사용하던 그 포워드라고 한다.

  • REQUEST : 클라이언트에서 온 요청
  • ERROR : 에러에 해당하는 요청
  • FORWARD : 서블릿에서 다른 서블릿이나 JSP를 호출할 때
  • INCLUDE : 서블릿에서 다른 서블릿이나 JSP의 결과를 포함할 때
  • ASYNC : 서블릿 비동기 호출

FilterRegistrationBean 에서 원하는 dispatcherType을 등록해주면, 그 타입일 때에만 Filter가 작동하게 된다.

**아무것도 적지 않았을 때에는 REQUEST일 때에만 작동한다고 한다.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함