Spring 2주차 마지막날. 오전에 심화과정 퀴즈를 봤다. 오늘 TIL은 프로젝트중 유용하게 썼던 예외 처리 방법에 대해 정리해보겠다.
: ResponseEntity를 이용해 예외 처리시 예외 메시지를 구성해준다.
@ExceptionHandler
: @Controller가 적용된 Bean에서 발생하는 예외를 잡아서 하나의 메서드에서 처리해주는 기능.
여기서 설정한 예외가 발생하면 handler가 실행된다. 컨트롤러 내부에서 호출한 Service에서 예외가 발생하더라도 잡아준다. 등록된 해당 컨트롤러 하나에만 적용이 된다.
@ControllerAdvice (@RestControllerAdvice)
: @Controller 가 적용된 모든 곳에서의 예외을 잡아준다. 전역에서 발생하는 예외를 잡아준다.
@RestControllerAdvice는 @ControllerAdvice와 같은 역할을 수행하면서 @ResponseBody로 객체를 리턴하는 역할까지 함께 수행한다.
단 AOP를 적용해 Controller의 예외만 잡아주기 때문에 Filter에서 발생한 예외는 처리하지 못한다. 필터 예외처리 방법은 TIL#32에서 다뤘다.
사용법
@RestControllerAdvice
public class GlobalExceptionHandler {
// throw로 발생시킨 오류 처리
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<MessageResponseDto> handleRuntimeException(RuntimeException e){
MessageResponseDto messageResponseDto = new MessageResponseDto(e.getMessage(), HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(messageResponseDto, messageResponseDto.getStatus());
}
// @Valid 오류 처리
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<MessageResponseDto> handleNotValidException(MethodArgumentNotValidException e){
String message = e.getFieldError().getDefaultMessage();
MessageResponseDto messageResponseDto = new MessageResponseDto(message, HttpStatus.BAD_REQUEST);
return new ResponseEntity<>(messageResponseDto, messageResponseDto.getStatus());
}
}
ResponseEntity에 아래의 메세지를 포함한 dto를 담아 에러메시지를 클라이언트에게 반환.
public class MessageResponseDto {
private String msg;
private HttpStatus status;
private int statusCode;
public MessageResponseDto(String msg,HttpStatus httpStatus) {
this.msg = msg;
this.status = httpStatus;
this.statusCode = httpStatus.value();
}
}