Spring에서의 예외 처리: @ExceptionHandler 활용
웹 애플리케이션을 개발할 때, 예외 처리는 매우 중요한 부분입니다. 사용자에게 발생한 오류에 대한 적절한 메시지를 제공하고, 시스템의 안정성을 높이기 위해 예외 처리는 필수적입니다. Spring 프레임워크는 예외 처리를 위한 여러 가지 방법을 제공하며, 그 중 하나가 바로 @ExceptionHandler입니다.
이 글에서는 @ExceptionHandler의 사용법과 활용법에 대해 자세히 알아보겠습니다.
1. @ExceptionHandler란?
@ExceptionHandler는 Spring MVC에서 발생하는 예외를 처리하는 데 사용되는 어노테이션입니다. 이 어노테이션을 사용하면, 특정 예외가 발생했을 때 이를 처리할 수 있는 메서드를 지정할 수 있습니다.
예를 들어, @ExceptionHandler를 사용하여 특정 예외가 발생했을 때 사용자에게 친절한 에러 메시지를 반환하거나, 로그를 기록하는 등의 작업을 할 수 있습니다.
2. 기본적인 사용법
@ExceptionHandler는 메서드에 적용하여 해당 메서드가 예외를 처리하도록 합니다. 기본적인 사용 예시는 다음과 같습니다.
@Controller
public class MyController {
@GetMapping("/test")
public String test() throws Exception {
// 예외를 일부러 발생시킴
throw new Exception("Something went wrong!");
}
@ExceptionHandler(Exception.class)
public String handleException(Exception e) {
// 예외를 처리하고 사용자에게 반환할 메시지를 반환
return "error";
}
}
위 코드에서 test() 메서드는 일부러 예외를 발생시킵니다. 예외가 발생하면, handleException() 메서드가 호출되어 해당 예외를 처리합니다. 이 메서드는 Exception 타입의 예외를 처리하고, "error"라는 뷰를 반환합니다.
3. 특정 예외 처리
@ExceptionHandler는 특정 예외만 처리하도록 설정할 수 있습니다. 예를 들어, NullPointerException이나 IllegalArgumentException과 같은 구체적인 예외를 처리할 수 있습니다.
@ExceptionHandler(NullPointerException.class)
public String handleNullPointerException(NullPointerException e) {
// NullPointerException 발생 시 처리할 로직
return "nullPointerError";
}
@ExceptionHandler(IllegalArgumentException.class)
public String handleIllegalArgumentException(IllegalArgumentException e) {
// IllegalArgumentException 발생 시 처리할 로직
return "illegalArgumentError";
}
이렇게 구체적인 예외를 처리하면, 각 예외에 맞는 맞춤형 에러 페이지나 메시지를 제공할 수 있습니다.
4. @ControllerAdvice와 결합하여 전역 예외 처리하기
@ExceptionHandler는 개별 컨트롤러에만 적용되는 반면, @ControllerAdvice를 사용하면 애플리케이션 전역에서 발생한 예외를 처리할 수 있습니다. @ControllerAdvice는 여러 컨트롤러에서 발생하는 예외를 공통적으로 처리하고자 할 때 유용합니다.
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception e) {
return new ResponseEntity<>("An error occurred: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
위의 코드에서 GlobalExceptionHandler 클래스는 @ControllerAdvice로 선언되어 있으며, Exception 예외를 전역적으로 처리합니다. 이 방식으로 작성하면, 모든 컨트롤러에서 발생하는 예외를 하나의 클래스로 처리할 수 있어 코드의 중복을 줄이고 유지보수를 쉽게 할 수 있습니다.
5. @ExceptionHandler와 @ResponseStatus의 차이점
@ExceptionHandler는 예외를 처리하는 방법을 정의하는데 사용됩니다. 그러나 예외를 처리할 때, 자동으로 HTTP 상태 코드를 설정하고 싶다면 @ResponseStatus 어노테이션을 사용할 수 있습니다.
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Resource Not Found")
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
이렇게 @ResponseStatus를 사용하면, 예외가 발생할 때 자동으로 상태 코드와 메시지가 반환됩니다. @ExceptionHandler와 @ResponseStatus를 적절히 활용하면 더욱 깔끔한 예외 처리 로직을 구현할 수 있습니다.
6. @ExceptionHandler 메서드는 예외 타입을 매개변수로 받아서 처리
@ExceptionHandler 메서드는 예외 타입을 매개변수로 받아서 처리할 수 있습니다. 예를 들어, 특정 예외가 발생했을 때 그 예외 객체를 메서드 매개변수로 전달받아 처리할 수 있습니다.
@ExceptionHandler는 지정한 예외가 발생했을 때, 해당 예외 객체를 자동으로 메서드의 매개변수로 전달합니다. 이를 통해 예외 객체를 활용하여 예외에 대한 추가 정보를 처리하거나, 예외의 메시지를 로깅하거나 사용자에게 알릴 수 있습니다.
예시 코드
@Controller
public class MyController {
@GetMapping("/test")
public String test() throws Exception {
// 예외를 일부러 발생시킴
throw new IllegalArgumentException("Invalid argument provided!");
}
@ExceptionHandler(IllegalArgumentException.class)
public String handleIllegalArgumentException(IllegalArgumentException e) {
// 예외 객체를 매개변수로 받아 처리
System.out.println("Exception occurred: " + e.getMessage());
return "illegalArgumentError"; // error 페이지 반환
}
}
설명
- test() 메서드에서는 일부러 IllegalArgumentException을 발생시키고 있습니다.
- @ExceptionHandler(IllegalArgumentException.class) 어노테이션이 붙은 handleIllegalArgumentException() 메서드는 IllegalArgumentException이 발생했을 때 호출됩니다.
- 이 메서드는 예외 객체(IllegalArgumentException e)를 매개변수로 받아, 예외 메시지 등을 처리할 수 있습니다.
예외 객체 활용
예외 객체를 매개변수로 받으면, 예외에 대한 세부 정보(예: 예외 메시지, 예외 코드, 트레이스 등)를 추가로 활용할 수 있습니다. 예를 들어, 예외가 발생한 원인에 대해 더 구체적인 응답을 만들거나, 로그에 예외 정보를 기록하는 등의 작업을 할 수 있습니다.
@ExceptionHandler(NullPointerException.class)
public ResponseEntity<String> handleNullPointerException(NullPointerException e) {
// 예외 메시지와 스택 트레이스를 포함한 응답
String errorMessage = "Null pointer exception occurred: " + e.getMessage();
return new ResponseEntity<>(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR);
}
7. 결론
@ExceptionHandler는 Spring 애플리케이션에서 예외 처리를 효과적으로 관리할 수 있는 강력한 도구입니다. 이 어노테이션을 사용하면 예외 발생 시 사용자에게 의미 있는 메시지를 전달하고, 시스템의 안정성을 향상시킬 수 있습니다. 또한 @ControllerAdvice와 결합하여 전역 예외 처리도 가능하므로, 복잡한 애플리케이션에서도 유연하게 예외를 관리할 수 있습니다.
적절한 예외 처리 로직을 구현하여 사용자 경험을 향상시키고, 코드 유지보수성을 높이는 데 @ExceptionHandler를 적극 활용해 보세요.