SpringSecurity를 이용해서 서버 인증 방식을 구현하던 도중 Filter에 대해서 궁금증이 생겼다. 여러 레퍼런스를 참고하다 보면 필터링 로직 구현이 조금씩 다른 것을 확인할 수 있다.
OncePerRequestFilter
를 사용하거나 GenericFilterBean
을 사용하는 것이었다. 두 방식의 차이점을 알아보고 무엇을 사용하면 좋을지를 고민해보자.
Filter
javax.servlet-api
나 tomcat-embed-core
를 사용하면 제공되는 Servlet Filter Interface
이다.DispatcherServlet
가 요청을 받기 전 앞단에 Filter
에서 먼저 request를 받는다.package jakarta.servlet;
import java.io.IOException;
public interface Filter {
default void init(FilterConfig filterConfig) throws ServletException {
}
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
default void destroy() {
}
}
GenericFilterBean
Filter
를 확장하여 Spring에서 제공하는 filterFilter
에서 얻어올 수 없는 정보였던 Spring의 설정 정보를 가져올 수 있게 확장된 추상 클래스 public abstract class GenericFilterBean implements Filter, BeanNameAware, EnvironmentAware,
EnvironmentCapable, ServletContextAware, InitializingBean, DisposableBean {
/** Logger available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private String beanName;
@Nullable
private Environment environment;
@Nullable
private ServletContext servletContext;
@Nullable
private FilterConfig filterConfig;
private final Set<String> requiredProperties = new HashSet<>(4);
...
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
문제는 의도치 않은 경우에 Filter가 두번씩 적용되는 경우가 있을 수 있다.
Filter
로 구현되어 있다.API 0
에서 요청을 처리하고 API 1
로 redirect 시킨다고 가정하자.이러한 문제를 해결하기 위해 OncePerRequestFilter
가 등장했다.
모든 서블릿에서 일관된 요청을 처리하기 위해 만들어진 필터이다.
이 추상 클래스를 구현한 필터는 사용자의 한번에 요청 당 딱 한번만 실행되는 필터를 만들 수 있다.
OncePerRequestFilter를 상속하여 구현한 경우 doFilter 대신 doFilterInternal 메서드를 구현하면 된다.
@Slf4j
@Component
public class FirstFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// TODO 전처리
filterChain.doFilter(request , response);
// TODO 후처리
}
}
참고
OncePerRequestFilter와 Filter의 차이
[Spring] OncePerRequestFilter란?
2) Springboot OncePerRequestFilter 와 GenericFilterBean의 차이
[Spring Boot] 나의 필터가 두 번 적용된 이유