Spring Boot는 별도의 예외 처리를 설정하지 않았을 때, BasicErrorController를 사용하여 처리되지 않은 예외를 자동으로 처리한다.
웹 브라우저에서 페이지를 요청했을 때 오류가 발생하면 Whitelabel Error Page 형식으로 응답하고, API 클라이언트가 서버에 요청했을 때 오류가 발생하면 JSON 형식으로 응답한다. 응답의 내용은 동일하다.
@ControllerAdvice와 @ExceptionHandlerSpring Boot에서 제공하는 강력하고 유연한 예외 처리 매커니즘으로, 가장 일반적이고 권장되는 전역 예외 처리 방식을 채택하여 어플리케이션의 모든 처리 과정에서 발생하는 에외를 한 곳에서 중앙 집중적으로 처리한다.
@ExceptionHandler: 현재 컨트롤러에 해당 예외를 처리하는 핸들러가 있는지 먼저 확인한다.@ControllerAdvice 내 @ExceptionHandler: 적절한 핸들러를 찾지 못하면 전역 예외 처리기에서 핸들러를 검색하고, 여러 @ControllerAdvice가 있다면 @Order 어노테이션으로 순서를 지정한다.ResponseStatusException: 위의 두 경우에 해당하지 않고 ResponseStatusException이 던져지면 Spring이 직접 처리한다.BasicErrorController가 처리하여, 기본적인 오류 페이지나 JSON 응답을 반환한다.@ControllerAdvice를 통한 에러 처리Spring 어플리케이션에서 전역적으로 예외를 처리하기 위해 사용하는 어노테이션이다. 역할에 따라 예외 처리를 분리하도록 여러 개를 사용할 수 있으나, 충돌을 피하고 의도한 대로 동작하게 하기 위해서는 @Order로 우선순위를 설정해야 한다.
@Data
public class HelloRequest {
@NotBlank(message="이름은 공백일 수 없습니다.")
private String name;
@Email(message="올바른 형식의 이메일 주소여야 합니다.")
private String email;
@Min(value=18, message="18세 이상이어야 합니다.")
private int age;
}
@ControllerAdvice // @RestControllerAdvice로 변경 가능
public class GlobalExceptionHandler {
// @Valid, @Validated(@RequestBody) 예외 처리
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
for (FieldError error : ex.getBindingResult().getFieldErrors()) {
errors.put(error.getField(), error.getDefaultMessage());
// 에러 발생 필드, 해당 필드 에러와 관련된 기본 메시지 (일반적으로 검증 어노테이션의 message 속성에 정의된 값)
}
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
}
// 기타 예외 (예: @ModelAttribute, @RequestParam 등)
// 필요 시 추가 처리
}
이름을 입력하지 않았을 경우 검증에 실패하여, error.getField()와 error.getDefaultMessage()는 각각 에러가 발생한 필드 name과 이름은 공백일 수 없습니다.를 반환한다.