위와 같이, 예외 발생 시 반환하는 응답의 구조를 customize하고자 한다!
앞에서 봤듯이, 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 클래스의 에러 구조를 반환하고 싶다 ‼️
ResponseEntityExceptionHandler클래스에는,
handleException 메서드
public final ResponseEntity<Object> handleException(Exception ex, WebRequest request) throws Exception {
handleException 메서드
는, error details가 formatted된 ResponseEntity를 리턴한다.-> 이제, handleException 메서드를 오버라이딩해서, ErrorDetails클래스에서 정의한 에러 구조가 반환되도록 해야 한다!
-> 즉, ResponseEntityExceptionHandler클래스를 extends해서, 예외처리코드를 구현하면 된다!
@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
메서드
@ExceptionHandler
-> 어떤 예외를 처리할 것인지 정의/users/8 URL같은 에러는 404 NOT FOUND 에러가 떠야 하므로, handleNotUserFoundException 메서드를 만들었다.
성공!
참고 및 출처
이 시리즈는 Udemy 강의의 내용을 정리한 것입니다.
https://www.udemy.com/course/spring-boot-and-spring-framework-korean/