개발
Spring Boot 필터·인터셉터에서 발생한 예외 처리 방법
스택큐힙리스트
2025. 7. 10. 17:55
반응형
Spring Boot 애플리케이션에서는 컨트롤러 진입 전 단계인 Filter나 Interceptor에서 인증·로깅·트래픽 제어 등의 처리를 하게 됩니다. 이 과정에서 예외가 발생할 수 있는데, 전통적인 @ControllerAdvice 전역 예외 처리 방식은 이 영역까지는 영향을 미치지 않습니다.
이번 포스팅에서는 필터와 인터셉터에서 예외가 발생했을 때 이를 어떻게 처리하고, 클라이언트에 일관된 에러 응답을 보낼 수 있는지에 대해 설명합니다.
✅ 왜 전역 예외 처리(@ControllerAdvice)로 잡히지 않을까?
@ControllerAdvice는 DispatcherServlet 이후 컨트롤러 진입 시점부터 발생한 예외만 처리합니다. 하지만 필터와 인터셉터는 그 이전 단계에서 실행되므로 @ControllerAdvice의 영향권 밖에 있습니다.
✅ Filter에서 예외 처리하기
Filter는 서블릿 단계에서 동작하기 때문에, 예외가 발생하면 직접 HTTP 응답을 조작해줘야 합니다.
@Component
public class JwtAuthFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
// JWT 토큰 검증 로직
chain.doFilter(request, response);
} catch (JwtException ex) {
HttpServletResponse res = (HttpServletResponse) response;
res.setStatus(HttpStatus.UNAUTHORIZED.value());
res.setContentType("application/json");
res.getWriter().write("{\"message\": \"토큰이 유효하지 않습니다.\"}");
}
}
}
- 필터 내부에서 직접 응답 코드와 메시지를 설정해야 합니다.
- ObjectMapper를 사용해 JSON 형태의 에러 응답을 만드는 것도 가능합니다.
✅ HandlerInterceptor에서 예외 처리하기
인터셉터는 비교적 DispatcherServlet에 가까운 레이어이지만, 여기서 발생한 예외도 @ControllerAdvice로는 처리되지 않습니다.
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
if (인증실패조건) {
throw new CustomAuthException("권한이 없습니다.");
}
return true;
}
}
이 경우, 아래와 같은 방식으로 ExceptionResolver를 구현하여 처리할 수 있습니다.
✅ 필터/인터셉터 예외 공통 처리 – HandlerExceptionResolver 활용
@Component
public class CustomExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
try {
response.setStatus(HttpStatus.FORBIDDEN.value());
response.setContentType("application/json");
response.getWriter().write("{\"message\": \"" + ex.getMessage() + "\"}");
response.getWriter().flush();
} catch (IOException e) {
// 로깅 처리
}
return new ModelAndView(); // 뷰 리졸빙 없이 직접 응답 처리
}
}
- Spring Boot가 예외 발생 시 HandlerExceptionResolver를 자동 호출
- @ControllerAdvice와 달리, 필터/인터셉터 예외에도 대응 가능
✅ 실무 팁
- 응답 포맷을 API 전체에서 통일하려면 ObjectMapper를 이용해 DTO 형태의 에러 메시지를 반환하도록 설계
- ExceptionResolver는 여러 개 등록 가능하며, Ordered 인터페이스로 우선순위 설정 가능
- Spring Security를 사용하는 경우 AuthenticationEntryPoint, AccessDeniedHandler를 활용해 예외 처리
반응형