package javax.servlet;
import java.io.IOException;
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()
필터 인스턴스 초기화 메서드
서블릿 컨테이너는 필터를 인스턴스화 한 후 한 번 init 메서드를 호출
👉 doFilter()
헤더, 매개변수 또는 속성을 추가하거나 수정하는 등 요청 및 응답 객체를 수정할 수 있음 (Interceptor는 객체 수정 못함)
FilterChain을 사용하여 체인의 다음 필터 또는 요청을 처리하는 서블릿을 호출할 수 있음
👉 destroy()
서블릿 컨테이너는 doFilter메서드 내의 모든 쓰레드가 종료되거나 설정한 제한 시간이 지난 후에 destroy 메서드를 한 번 호출하며, 이후에는 해당 필터의 인스턴스로는 doFilter를 호출하지 않는다.
@WebFilter(urlPatterns = {"/api/*"}, asyncSupported = true)
@Component
@RequiredArgsConstructor
public class AccessLogFilter extends OncePerRequestFilter {
private final AccessLogger accessLogger;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
long stime = System.currentTimeMillis();
try {
chain.doFilter(request, response);
} finally {
long etime = System.currentTimeMillis();
long elapsed = etime - stime;
accessLogger.log(request, response, elapsed);
}
}
}
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
}
👉 preHandle()
요청이 컨트롤러에 의해 처리되기 전에 호출됨
요청을 계속 처리해야 하는지 또는 중지해야 하는지를 나타내는 boolean 값을 리턴 (false면 작업 중단)
👉 postHandle()
요청이 컨트롤러에 의해 처리된 후 view가 렌더링되기 전에 호출됨
model과 view를 수정하는데 사용 가능
👉 afterCompletion()
뷰가 렌더링된 후 호출됨
로깅, 리소스 반환과 같은 정리 작업을 수행하는 데 사용
@Component
@RequiredArgsConstructor
public class JwtTokenInterceptor implements HandlerInterceptor {
private final JwtTokenProvider jwtTokenProvider;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("JwtToken 호출");
String accessToken = request.getHeader("ACCESS_TOKEN");
System.out.println("AccessToken:" + accessToken);
String refreshToken = request.getHeader("REFRESH_TOKEN");
System.out.println("RefreshToken:" + refreshToken);
if (jwtTokenProvider.isValidAccessToken(accessToken) && jwtTokenProvider.isValidRefreshToken(refreshToken)) {
return true;
}else{
throw new RequestException(ErrorCode.JWT_BAD_TOKEN_401);
}
}
}