보통 우리가 MVC 구조의 코드를 구현하다보면 필연적으로 나오는게 Exception 처리 즉 예외처리를 하고는 한다. 이를 구현해주는게 스프링에서는 ExceptionHandler가 있다. 과연 스프링 ExceptionHandler는 어떻게 동작하는지 알아보자
@ControllerAdvice 또는 특정 컨트롤러 클래스 내에 특정 예외가 발생했을 때 이를 처리하기 위한 메서드를 정의할 수 있도록 지원하는 어노테이션이고 이를 통해 예외 발생 시 프로그램의 흐름을 중단하지 않고, 오류를 보다 유연하게 처리하거나 사용자에게 알맞은 메시지를 반환하게 한다.
즉 예외 처리를 WAS로 바로 넘기는게 아니라 이를 직접처리하여 로깅 혹은 유저 친화적인 에러 메시지로 변경할 수 있다는 것이 중요하다.
예시를 보면 아래와 같다.
@RestController
public class MyController {
@ExceptionHandler(NullPointerException.class)
public ResponseEntity<String> handleNullPointerException(NullPointerException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Null 값이 발생했습니다: " + e.getMessage());
}
위에서는 nullPointerException이 발생했을 시 ExeceptionHandler의 사용자 정의 메서드를 정의하여 특정 메시지를 반환해주는 로직을 추가했다.
위에서 봤다시피 @ExeceptionHandler의 큰 장점은 에러 발생 시 was에 넘기기 전에 사용자 정의 메서드를 거친다는 것이다. 이 뿐만이 아니라 몇가지 장점이 더 있는데 아래와 같다.
아래 예시를 보면 이해가 빠를 것이다.
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(NullPointerException.class)
public ResponseEntity<String> handleNullPointerException(NullPointerException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body("Null 값이 발생했습니다.");
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGenericException(Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("서버 오류가 발생했습니다.");
}
}
예시의 동작 흐름을 살펴보면