Spring에서는 예외 처리를 좀 더 편리하게 관리하고, 사용자에게 전달할 에러 메시지를 체계적으로 관리할 수 있는 기능을 제공합니다. 이를 통해 코드의 중복을 줄이고 유지보수를 쉽게 만들며, 효율적인 에러 메시지 관리는 사용자에게 명확한 피드백을 제공할 수 있습니다.
Spring은 애플리케이션 전체에서 발생하는 예외를 한 곳에서 처리할 수 있도록 @ControllerAdvice
와 @ExceptionHandler
라는 기능을 제공합니다. 이 기능을 활용하면 각 컨트롤러에서 예외 처리를 반복할 필요 없이, 전역적으로 예외를 관리할 수 있어 훨씬 간편합니다.
@ControllerAdvice
로 전역 예외 처리하기@RestControllerAdvice
활용@ControllerAdvice
와 @ResponseBody
를 결합한 형태로, RESTful 서비스에서 예외 발생 시 JSON 형태로 응답을 보내는 데 유용합니다.아래는 @RestControllerAdvice
와 @ExceptionHandler
를 사용해 글로벌 예외 처리를 구현한 예시입니다. 특정 예외가 발생하면 정의한 HTTP 응답과 함께 에러 메시지를 전달합니다.
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler({IllegalArgumentException.class})
public ResponseEntity<RestApiException> handleIllegalArgumentException(IllegalArgumentException ex) {
RestApiException restApiException = new RestApiException(ex.getMessage(), HttpStatus.BAD_REQUEST.value());
return new ResponseEntity<>(restApiException, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler({NullPointerException.class})
public ResponseEntity<RestApiException> handleNullPointerException(NullPointerException ex) {
RestApiException restApiException = new RestApiException(ex.getMessage(), HttpStatus.NOT_FOUND.value());
return new ResponseEntity<>(restApiException, HttpStatus.NOT_FOUND);
}
}
예외를 처리할 때 에러 메시지를 코드에 직접 작성하지 않고, properties 파일을 사용해 관리하면 메시지 변경이나 다국어 지원이 쉬워집니다. Spring에서는 messages.properties
파일에 에러 메시지를 작성하고, 이 파일의 메시지를 MessageSource
를 통해 불러와 사용할 수 있습니다.
에러 메시지를 properties 파일에 정의해 두면, 언제든지 메시지를 업데이트하거나 다국어로 확장할 수 있습니다.
below.min.my.price=최저 희망가는 최소 {0}원 이상으로 설정해 주세요.
not.found.product=해당 상품이 존재하지 않습니다.
MessageSource
를 통해 에러 메시지를 키 값과 매개변수로 불러올 수 있습니다. 예를 들어, 아래와 같이 최소 가격을 설정하는 메시지를 가져올 수 있습니다.
@Autowired
private MessageSource messageSource;
public ProductResponseDto updateProduct(Long id, ProductMypriceRequestDto requestDto) {
if (requestDto.getMyprice() < MIN_MY_PRICE) {
throw new IllegalArgumentException(
messageSource.getMessage("below.min.my.price", new Object[]{MIN_MY_PRICE}, Locale.getDefault())
);
}
// ...
}
예외를 좀 더 구체적으로 다루기 위해 커스텀 예외 클래스를 만들 수도 있습니다. 이렇게 하면 특정 상황에 맞는 메시지를 보다 직관적으로 전달할 수 있습니다.
public class ProductNotFoundException extends RuntimeException {
public ProductNotFoundException(String message) {
super(message);
}
}
ProductNotFoundException
예외가 발생할 때도, 글로벌 예외 핸들러를 통해 에러 응답을 관리할 수 있습니다.
@ExceptionHandler({ProductNotFoundException.class})
public ResponseEntity<RestApiException> handleProductNotFoundException(ProductNotFoundException ex) {
RestApiException restApiException = new RestApiException(ex.getMessage(), HttpStatus.NOT_FOUND.value());
return new ResponseEntity<>(restApiException, HttpStatus.NOT_FOUND);
}
MessageSource
를 사용하여 다국어와 상황에 맞는 에러 메시지를 제공합니다.