[REST API] 모든 resource에 대해 예외 메세지 구조 customize하기

민지·2024년 3월 13일
0

REST API - Spring Boot

목록 보기
11/27

뭘 할건지?


위와 같이, 예외 발생 시 반환하는 응답의 구조를 customize하고자 한다!

수정 1 : custom response structure 정의할 java bean 만들기 - ErrorDetails클래스

앞에서 봤듯이, custom response structure에는 timestamp, message, details 멤버변수로 구성되었다.
이를 저장할 자바 클래스를 만들었다.

package com.minjiki2.rest.webservices.restfulwebservices.exception;

import java.time.LocalDateTime;

public class ErrorDetails {
	// timestamp : 에러 발생 시간
	// message : 에러 메시지
	// details : 에러 상세 정보

	private LocalDateTime timestamp;
	private String message;
	private String details;

	// Constructor
	public ErrorDetails(LocalDateTime timestamp, String message, String details) {
		super();
		this.timestamp = timestamp;
		this.message = message;
		this.details = details;
	}

	// getters
	public LocalDateTime getTimestamp() {
		return timestamp;
	}

	public String getMessage() {
		return message;
	}

	public String getDetails() {
		return details;
	}

}

예외가 발생하면, ErrorDetails 클래스의 에러 구조를 반환하고 싶다 ‼️

Spring MVC가 발생시키는 모든 에러를 처리해주는, ResponseEntityExceptionHandler 클래스

ResponseEntityExceptionHandler클래스에는,

  • spring mvc가 발생시키는 모든 에러를 처리해주는 메서드들이 모여있다.
  • 개발자(나)가 정의된 에러 정보를 반환한다. -> "returning ResponseEntity with formatted error details in the body"
  • 가장 기본적인 에러 처리 메서드 - handleException 메서드
    public final ResponseEntity<Object> handleException(Exception ex, WebRequest request) throws Exception {
    handleException 메서드는, error details가 formatted된 ResponseEntity를 리턴한다.

-> 이제, handleException 메서드를 오버라이딩해서, ErrorDetails클래스에서 정의한 에러 구조가 반환되도록 해야 한다!
-> 즉, ResponseEntityExceptionHandler클래스를 extends해서, 예외처리코드를 구현하면 된다!

수정 2 : CustomizedResponseEntityExceptionHandler 클래스

@ControllerAdvice
public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

	@ExceptionHandler(Exception.class) // 발생할 모든 exception을 처리할 것
	public final ResponseEntity<ErrorDetails> handleAllException(Exception ex, WebRequest request) throws Exception {
		// 우리가 정의한 custom exception structure 만들기
		ErrorDetails errorDetails = new ErrorDetails(LocalDateTime.now(), ex.getMessage(),
				request.getDescription(false));
		// 만든 예외구조를 반환하는 기능
		return new ResponseEntity<ErrorDetails>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
	}

	@ExceptionHandler(UserNotFoundException.class)
	public final ResponseEntity<ErrorDetails> handleUserNotFoundException(Exception ex, WebRequest request)
			throws Exception {

		ErrorDetails errorDetails = new ErrorDetails(LocalDateTime.now(), ex.getMessage(),
				request.getDescription(false));

		return new ResponseEntity<ErrorDetails>(errorDetails, HttpStatus.NOT_FOUND);

	}
}
  • @ControllerAdvice 어노테이션
    한마디로, 해당 클래스를, 모든 컨트롤러에 적용하고 싶을 때 사용한다!

    @ControllerAdvice 어노테이션은, 전역에서 발생할 수 있는 예외를 잡아 처리하거나, 모든 컨트롤러에 공통적으로 적용될 속성 및 메서드를 정의할 때 사용된다. 즉, 이 어노테이션이 적용된 클래스는, 어플리케이션 내의 모든 컨트롤러에 전역적으로 적용된다!

  • handleAllException 메서드

    • ResponseEntityExceptionHandler 클래스의 → handleException 메서드 선언부분을 복사해옴
    • @ExceptionHandler -> 어떤 예외를 처리할 것인지 정의
  • /users/8 URL같은 에러는 404 NOT FOUND 에러가 떠야 하므로, handleNotUserFoundException 메서드를 만들었다.

최종 실행결과


성공!




참고 및 출처
이 시리즈는 Udemy 강의의 내용을 정리한 것입니다.
https://www.udemy.com/course/spring-boot-and-spring-framework-korean/

profile
배운 내용을 바로바로 기록하자!

0개의 댓글