[SpringBoot] 예외 처리 (ExceptionHandler)

김선형·2025년 9월 9일

Java

목록 보기
20/27

개요

Spring Boot는 별도의 예외 처리를 설정하지 않았을 때, BasicErrorController를 사용하여 처리되지 않은 예외를 자동으로 처리한다.
웹 브라우저에서 페이지를 요청했을 때 오류가 발생하면 Whitelabel Error Page 형식으로 응답하고, API 클라이언트가 서버에 요청했을 때 오류가 발생하면 JSON 형식으로 응답한다. 응답의 내용은 동일하다.

@ControllerAdvice@ExceptionHandler

Spring Boot에서 제공하는 강력하고 유연한 예외 처리 매커니즘으로, 가장 일반적이고 권장되는 전역 예외 처리 방식을 채택하여 어플리케이션의 모든 처리 과정에서 발생하는 에외를 한 곳에서 중앙 집중적으로 처리한다.

예외 처리 우선순위

  • 컨트롤러 내 @ExceptionHandler: 현재 컨트롤러에 해당 예외를 처리하는 핸들러가 있는지 먼저 확인한다.
  • @ControllerAdvice@ExceptionHandler: 적절한 핸들러를 찾지 못하면 전역 예외 처리기에서 핸들러를 검색하고, 여러 @ControllerAdvice가 있다면 @Order 어노테이션으로 순서를 지정한다.
  • ResponseStatusException: 위의 두 경우에 해당하지 않고 ResponseStatusException이 던져지면 Spring이 직접 처리한다.
  • Spring Boot 기본 예외 처리: 위의 어떤 방법으로도 처리되지 않은 예외는 Spring Boot의 기본 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이름은 공백일 수 없습니다.를 반환한다.

profile
선형의 비선형적 기록 🐜

0개의 댓글