@ControllerAdvice와 @ExceptionHandler란?
스프링은 @ControllerAdvice와 @ExceptionHandler를 통해 특정 컨트롤러 또는 전역적으로 발생하는 예외를 처리할 수 있도록 지원한다. 이 접근법을 사용하면 코드 중복 없이 일관된 에러 응답을 클라이언트에게 반환할 수 있다.
글로벌 API 예외 처리
공통적으로 API 예외를 처리하는 예제
1) 공통 응답 처리를 위한 응답 객체 생성

2) InvalidPasswordException 정의

3) GlobalExceptionHandler 클래스

- @ExceptionHandler(InvalidPasswordException.class)
- @ExceptionHandler는 지정된 예외가 발생했을 때 자동으로 해당 메서드가 호출되도록 설정하는 스프링의 어노테이션
- 여기서는 InvalidPasswordException이 발생했을 때 이 메서드가 실행된다.
- public ResponseEntity<ErrorResponse> handlerInvalidPasswordException(InvalidPasswordException e)
- 반환 타입은 ResponseEntity<ErrorResponse>로, HTTP 응답과 함께 사용자 정의 에러 객체(ErrorResponse)를 반환한다.
- InvalidPasswordException 객체를 매개변수로 받아 예외 메시지와 추가 정보를 처리한다.
- ErrorResponse errorResponse = new ErrorResponse(e.getMessage(), HttpStatus.UNAUTHORIZED.value())
- e.getMessage() : 예외 객체에서 전달된 메시지를 가져온다.
- HttpStatus.UNAUTHORIZED.value() : HTTP 상태 코드 401을 숫자값으로 반환한다.
- ErrorResponse : 예외 메시지와 상태 코드를 포함하는 응답 객체를 생성한다.
- return new ResponseEntity<>(errorResponse, HttpStatus.UNAUTHORIZED);
- ResponseEntity : HTTP 응답 객체로, 본문(body)과 상태 코드(status)를 포함한다.
- errorResponse : 반환할 응답 객체로, 사용자 정의 메시지와 상태 코드가 포함되어 있다.
- HttpStatus.UNAUTHORIZED: HTTP상태 코드 401을 설정한다.
4) 오류 응답 데이터

작동 흐름
- 예외 발생 : 비밀번호가 일치하지 않아 InvalidPasswordException이 발생
- 예외 핸들러 실행 : @ExceptionHandler가 예외를 가로채고, 해당 메서드가 호출된다.
- ErrorResponse 생성 : 클라이언트에게 반환할 에러 메시지와 상태 코드가 포함된 응답 객체를 생성한다.
- 로그 기록 : 예외 메시지를 로그에 기록하여 디버깅 활용.
- HTTP 응답 반환 : 상태 코드 401과 함께 에러 응답 객체를 클라이언트로 반환
[클라이언트]
↓ 요청
[컨트롤러 메서드]
↓
[예외 발생] (InvalidPasswordException)
↓
[GlobalExceptionHandler]
↓ @ExceptionHandler 매핑
[예외 처리 핸들러 실행]
↓
[ErrorResponse 객체 생성]
↓
[HTTP 응답 생성 (ResponseEntity)]
↓
[HTTP 응답 반환 (401)]
↓
[클라이언트로 에러 메시지 반환]
@Valid 검증 실패 예외 처리
@Valid는 DTO 클래스의 필드에 제약 조건을 설정하고, 이를 기반으로 입력값 검증을 수행하는데 사용된다. 검증 실패시 MethodArgumentNotValidException이 발생한다.
공통적으로 @Valid 검증 실패 예외를 처리하는 예제
0) DTO 클래스
@Getter
public class UserDTO {
@NotBlank(message = "이름은 필수 입력 항목입니다.")
@Size(min = 2, max = 20, message = "이름은 2자 이상, 20자 이하여야 합니다.")
private String name;
@NotBlank(message = "이메일은 필수 입력 항목입니다.")
private String email;
}
1) 공통 응답 처리를 위한 객체 생성

2) GlobalExceptionHandler 클래스

- 예외 핸들러 선언
- @ExceptionHandler(MethodArgumentNotValidException.class)
- @ExceptionHandler는 특정 예외가 발생했을 때 해당 메서드로 처리를 위임하는 역할
- 여기서는 MethodArgumentNotValidException 예외가 발생하면 이 메서드가 호출된다.
- 메서드 시그니처
- public ResponseEntity<ErrorResponse> handlerMethodArgumentNotValidException(MethodArgumentNotValidException e)
- 이 메서드는 MethodArgumentNotValidException을 매개변수로 받아 처리하며, ResponseEntity 객체를 반환한다.
- 예외 메시지와 상태 코드를 담은 ErrorResponse 객체를 클라이언트에게 반환
- public ResponseEntity<ErrorResponse> handlerMethodArgumentNotValidException(MethodArgumentNotValidException e)
- 에러 메시지 저장을 위한 Map 생성
- Map<String, String> errors = new HashMap<>();
- 검증 실패한 필드 이름과 해당 에러 메시지를 저장하기 위해 HashMap을 생성한다.
- 필드 이름(Key)와 에러 메시지(Value)를 저장할 자료 구조를 초기화한다.
- Map<String, String> errors = new HashMap<>();
- 검증 실패 정보 가져오기
- e.getBindingResult().getFieldErrors()
.forEach(error -> errors.put(error.getField(), error.getDefaultMessage()));- getBindingResult() : 검증 실패 결과를 가져옴.
- getFieldErrors() : 필드별 검증 실패 목록을 반환한다.
- forEach(...) : 각 필드 에러를 순회하며, 필드 이름(getField())과 에러 메시지를 errors 맵에 저장한다.
- 모든 검증 실패 항목을 처리하여, 필드 이름과 해당 에러 메시지 쌍으로 저장.
- e.getBindingResult().getFieldErrors()
- ErrorResponse 객체 생성
- ErrorResponse errorResponse = new ErrorResponse(errors.toString(), HttpStatus.BAD_REQUEST.value());
- errors.toString() : 저장된 에러 메시지를 문자열로 변환
- HttpStatus.BAD_REQUEST.value() : HTTP 400 상태 코드를 설정
- ErrorResponse : 메시지와 상태 코드를 포함하는 응답 객체를 생성한다.
- 검증 실패 메시지와 상태 코드를 담은 ErrorResponse 객체를 생성한다.
- ErrorResponse errorResponse = new ErrorResponse(errors.toString(), HttpStatus.BAD_REQUEST.value());
- ResponseEntity로 응답 반환
- return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
- ResponseEntity를 생성하며, 응답 본문으로 ErrorResponse 객체를 포함한다.
- HTTP 상태 코드를 400으로 설정한다.
- 클라이언트에게 검증 실패 메시지와 상태 코드가 포함된 HTTP 응답을 반환
- return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
3) 오류 응답 데이터

- 클라이언트 요청: 데이터를 전송하며 DTO 검증 조건에 맞지 않는 값을 포함할 수 있음.
- 유효성 검증: 스프링이 @Valid 어노테이션을 기반으로 데이터를 검증.
- 예외 발생: 검증 실패 시 MethodArgumentNotValidException 예외가 발생.
- 예외 처리: @ExceptionHandler 메서드가 예외를 가로채고 상세 검증 정보를 처리.
- 응답 반환: 클라이언트에게 유효성 검증 실패 메시지와 상태 코드(400)를 반환.
[클라이언트]
↓ 요청
[컨트롤러 메서드]
↓ 데이터 매핑 및 @Valid 검증
[유효성 검증 실패]
↓ 예외 발생 (MethodArgumentNotValidException)
[GlobalExceptionHandler]
↓
[예외 처리 핸들러 실행]
↓
[응답 생성 (ErrorResponse)]
↓
[HTTP 400 응답]
↓
[클라이언트로 응답 반환]'Back-End > Spring-MVC' 카테고리의 다른 글
| JWT 기반 인증 및 역할별 API 설계와 구현 : 관리자와 사용자 권한 처리 (0) | 2025.01.06 |
|---|---|
| JWT(Json Web Token) (0) | 2025.01.04 |
| Servlet Filter (0) | 2024.12.12 |
| Cookie와 Session (0) | 2024.12.12 |
| HTTP 요청 / 응답 조합 상황별 사용 (0) | 2024.12.02 |