@Override
init(final FilterConfig filterConfig) throws ServeletException {
log.info("LoginFiler.init");
}
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) {
log.info("LoginFilter.doFiler");
HttpServletRequest servletRequest = (HttpServletRequest) request;
try {
validateToken(servletRequest);
chain.doFiler(request, response);
} catch(Exception e) {
HttpServletResponse servletResponse = (HttpServletResponse) response;
servletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
}
}
public interface FilterChain {
public void doFiler(ServletRequest request, ServletResponse response) throws IOException, ServletException;
}
@Override
public void destroy() {
log.info("LoginFilter.destroy");
}
@Slf4j
@Component
pulbic class LoginFilter implements Filter {
@Slf4j
@WebFilter(urlPatterns = "/users/me/*")
public class LoginFilter implements Filter {
@SpringBootApplication
@ServletComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@Bean
public FilterRegistrationBean addFilter() {
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.serFilter(new LoginFilter(jwtTokenProvider));
filterRegistrationBean.setOrder(1);
filterRegistrationBean.addUrlPatterns("/users/me/*");
return filterRegistrationBean;
}
- pos가 0인 Filter의 doFilter 실행 -> chain.doFilter 호출
- pos가 1인 Filter의 doFilter 실행 -> chain.doFilter 호출
- ...
...
필터의 개수만큼 반복하며 doFilter 호출로 다음 필터를 호출함(doFilter를 무조건 호출해야 함)
@Configuration
public class WebConfig implements WebMvcConfugurer {
private final LoginInterceptor loginInterceptor;
public WebConfig(LoginInterceptor loginInterceptor) {
this.loginInterceptor = loginInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/signup", "/login");
}
}
addInterceptors
라는 메서드를 오버라이드해서 추가할 수 있음필터 | 인터셉터 |
---|---|
자바 표준 스펙 | 스프링이 제공하는 기술 |
다음 필터 실행을 위해 개발자가 명시적 작성 (doFilter) | 다음 인터셉터 실행을 위해 개발자가 신경써야 하는 부분이 없다 |
ServletRequest, ServletResponse를 필터 체이닝 중간에 새로운 객체로 바꿀 수 있다. | ServletRequest, ServletResponse를 인터셉터 체이닝 중간에 새로운 객체로 바꿀 수 없다. |
필터에서 예외가 발생하면 @ControllerAdvice에서 처리하지 못한다. | 인터셉터에서 예외가 발생하면 @ControllerAdvice에서 처리가 가능하다. |
@ControllerAdvice
의 적용 범위는 dispatcherServlet 내부 동작Spring에서 제공하는 기본 Filter들의 공통점 : 전문적 Web 관련 로직
Interceptor : ModelAttribute binding 속성들을 Request에 넣어주거나 Spring 관련 작업
관심사의 분리로 생각하면 좋을 듯
기준을 잘 정하는게 좋음!