try-catch 블록에서 catch(Exception e) 와 같이 처음부터 모든 예외를 처리하는 방법을 사용하지 않고, 다른 예외 처리를 먼저 하고 마지막에 Exception을 선언하는가?
예외처리 방식에서 @(Rest)ControllerAdvice 애너테이션 vs try-catch문 차이가 무엇일까?
✔️ 애너테이션 예외 처리 예제
@RestControllerAdvice
public class GlobalExceptionAdvice {
@ExceptionHandler(BusinessLogicException.class)
public ResponseEntity<?> handleBusinessLogicException(BusinessLogicException e) {
HttpHeaders headers = new HttpHeaders();
headers.add("BBANGBBANG_EXCEPTION", String.valueOf(e.getExceptionCode().getStatus()));
return ResponseEntity.ok().headers(headers).body(e.getMessage());
}
}
✔️ try-catch문 예외 처리 예제
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
Map<String, Object> claims = verifyJws(request, response);
setAuthenticationToContext(claims);
} catch (ResponseStatusException be) {
if (be.getStatus() == HttpStatus.UNAUTHORIZED) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, be.getMessage());
return;
}
request.setAttribute("exception", be);
} catch (SignatureException se) {
request.setAttribute("exception", se);
} catch (ExpiredJwtException ee) {
request.setAttribute("exception", ee);
} catch (Exception e) { // 최고조상 -> 마지막 catch문에
request.setAttribute("exception", e);
}
filterChain.doFilter(request, response);
}
1. ResponseStatusException 처리:
- ResponseStatusException 이 발생하면 특정 HTTP 응답 코드로 응답하고, 메세지를 클라이언트로 전달하고 있습니다.
2. SignatureException, ExpiredJwtException 처리:
- 각각의 예외에 대해서는 request.setAttribute("exception", ...) 를 통해 예외를 저장하고 있습니다. 이렇게 함으로써, 필터를 실행하는 도중 발생한 예외를 서블릿 컨테이너에게 전달하고자 합니다.
3. 그 외 모든 예외 처리:
- 가장 상위 클래스의 Exception 타입으로 모든 예외를 처리합니다. 이 경우에도 request.setAttribute("exception", ...) 를 통해 예외를 저장하고 있습니다.
✅ try-catch문을 사용하면 세밀한 예외 처리 로직을 정의할 수 있습니다. 특정 예외에 대한 세부적인 처리가 필요한 경우, 애너테이션보다 catch 블록이 더 유연하게 대응할 수 있습니다.
✅ try-catch문 자체는 Java 언어의 기본 문법 중 하나로, 어떠한 프레임워크를 사용하든 일반적으로 예외 처리를 위해 사용될 수 있지만, 위 코드 내부의 로직을 살펴보면 Spring 프레임워크를 활용하여 HTTP응답을 처리하고 예외를 저장하는 로직으로 이루어져 있습니다.