API에서 예외 발생시 공통응답으로 처리하는 Advice 클래스 : @RestControllerAdvice , @ExceptionHandler

TopOfTheHead·2025년 11월 11일

Spring Boot

목록 보기
22/25

어플리케이션전역적 범위API에서 예외 발생 시 통일된 FormatDTO클라이언트에게 응답
@RestControllerAdvice가 선언된 Advice 용도클래스를 정의 및 내부에 특정 예외 발생 시 처리하는 Logic을 작성한 @ExceptionHandler가 정의된 메서드를 정의

@ExceptionHandler에 정의된 예외의 경우 구체화예외가 선언된 메서드를 우선적으로 실행하여 처리
MethodArgumentNotValidException가 발생할 경우 Exception보다 구체화MethodArgumentNotValidException를 처리하는 메서드를 먼저 처리한다.

API에서 MethodArgumentNotValidException 발생 시 처리하는 로직 작성하기

  • @RestControllerAdvice가 선언된 Advice 클래스에서 예외 처리에 대한 Logic을 작성
    @RestControllerAdvice어플리케이션에서 전역적으로 발생하는 예외를 catch하여 선언된 클래스로 전달

  • 일관성있는 JSON format응답클라이언트로 전달하기위해 DTO를 하나로 통일
    。해당 DTO객체DTO정적팩토리메서드ResponseEntity에 포함되어 생성 후 반환
 @Getter
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class ApiErrorResponse {
	private final String code;
	private final String message;
	public static ResponseEntity<ApiErrorResponse> toResponseEntity(
		HttpStatus httpStatus,
		String message
	) {
		return ResponseEntity
			.status(httpStatus)
			.body(
				new ApiErrorResponse(
					httpStatus.toString(),
					message
				)
			);
	}
}
  • DTO 객체를 포함한 ResponseEntity<DTO>를 반환하는 정적 팩토리 메서드 정의
    。해당 메서드HttpStatus객체String을 전달받아 DTO 객체 생성 후 ResponseEntity를 생성하여 반환

  • 지정된 Exception 발생 시 처리하는 @ExceptionHandler 메서드 정의
    。해당 Exception 발생 시 자동으로 catch하여 내부 logic을 실행
    객체를 반환하도록 설정 시 @ControllerAdvice 클래스에 의해 JSON으로 직렬화되어 Message Body에 포함
// 어플리케이션 전역적으로 API에서 발생하는 예외를 가져온다.
// 각 @ExceptionHandler에서 지정된 예외를 처리
@Hidden
@Slf4j
@RestControllerAdvice
public class ApiAdvice {
	// 가장 후순위로 예외를 처리하는 메서드
	@ExceptionHandler(Exception.class)
	public ResponseEntity<ApiErrorResponse> handleException(Exception e) {
		log.error(e.getMessage(), e);
		return ApiErrorResponse.toResponseEntity(
			ErrorCode.INTERNAL_SERVER_ERROR.getStatus(),
			ErrorCode.INTERNAL_SERVER_ERROR.getMessage()
		);
	}
	// 사용자 정의 예외를 처리하는 메서드
	@ExceptionHandler(CustomException.class)
	public ResponseEntity<ApiErrorResponse> handleCustomException(CustomException e) {
		return ApiErrorResponse.toResponseEntity(
			e.getStatus(),
			e.getMessage()
		);
	}
}

CustomException 발생 시 해당 ExceptionHttpStatus.BAD_REQUEST, "삭제된 계정이 아닙니다"라는 데이터가 포함된 경우 해당 데이터를 기반으로 ApiErrorResponseDTO를 생성 및 ResponseEntityWrapping하여 클라이언트에게 응답

MethodArgumentNotValidException가 발생할 경우 Exception보다 구체화MethodArgumentNotValidException를 처리하는 메서드를 우선적으로 실행하여 처리

▶ 사용자가 정의한 Custom Exception도 발생한 경우 catch하여 처리할 수 있다.
사용자 정의 예외

@RestControllerAdvice
Controller의 모든 @RequestMapping, @GetMapping, @PostMapping 등의 REST API Endpoint에서 발생하는 Exception어노테이션이 선언된 Advice 용도클래스로 유도

@ControllerAdvice + @ResponseBody가 결합된 형태로서 예외 발생 시 처리되어 반환되는 자바객체는 자동으로 JSON으로 직렬화되어 Message Body에 포함되어 클라이언트에게 전달

Swagger를 통한 문서화를 수행하는 경우 @Hidden을 선언하여 숨겨야한다.

@ExceptionHandler(처리할예외.class)
。지정한 Exception Type을 처리하는 Logic이 작성된 메서드에 선언하는 어노테이션
▶ 지정한 Exception이 발생한 경우 자동으로 catch하여 메서드 내부 로직대로 처리
Exception Type클래스 리터럴로 지정 ( ex. Exception.class )

@ExceptionHandler에 정의된 예외의 경우 구체화예외가 선언된 메서드를 우선적으로 실행하여 처리
Exception이 가장 후순위

Controller 내부 메서드에 선언 시 해당 ControllerAPI에서 발생되는 예외에만 적용
@RestControllerAdvice이 선언된 Advice 클래스 내부 메서드에 선언 시 전역적으로 발생하는 예외에 적용

  • @ExceptionHandler({예외1.class, 예외2.class , ... })
    중괄호를 통한 배열 형태로 처리할 여러 예외를 한번에 지정가능.
profile
공부기록 블로그

0개의 댓글