본문 바로가기
내일배움캠프

내일배움캠프TIL - @RestControllerAdvice

by Kiwimel0n 2024. 2. 14.

뉴스피드 프로젝트를 하게 되면서 api 요청에 대한 예외처리 응답을 따로따로 관리해주기가 힘들어 이것을 관리해 주는 것이 필요로 하였다. 

이러한 부분을 해결하기위해 스프링 부트에서 제공하는

@RestControllerAdvice를 사용하여 예외처리를 하게 되었다.

RestControllerAdvice는 주로 @RestController + @RestControllerAdvice + @ExceptionHandler 조합으로 사용된다.

 

먼저 예외를 담아서 Client에 보내줄 객체를 만든다.

@Getter
@Setter
@AllArgsConstructor
public class ExceptionDto {

    private int statusCode;
    private HttpStatus state;
    private String message;
}

 

그리고 전역으로 예외를 처리해줄 @RestControllerAdvice를 포함한 핸들러인 GlobalExceptionHandler 구현해준다.

 

@RestControllerAdvice
// @RestControllerAdvice 어노테이션을 통해 모든 컨트롤러에서 발생하는 예외를 catch함
public class GlobalExceptionHandler {

@ExceptionHandler(AccessDeniedException.class)
//ExceptionHandler 에노테이션을 사용하여 이러한 예외처리가 발생했을 시 밑의 문장을 실행 시켜준다.
    public ResponseEntity<ExceptionDto> AccessDeniedException(AccessDeniedException e){
 // 사용자에게 넘길 값을 ResponseEntity 객체를 통해서 전달
        return ResponseEntity.badRequest()
                .body(new ExceptionDto(HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST,
                        e.getMessage()));
    }
    
      @ExceptionHandler(value = {Exception.class})
  public catchException(ArithmeticException e) {
  // 예외 처리 시 실행될 문장...
  }

    
}

 

 

뉴스피드 프로젝트 중에 예외처리 예제로

checkUserID라는 메서드를 예제로 봐보겠다.

 private void checkUserID(User user, Post post) {
        if(user.getId() != null && !Objects.equals(post.getUser().getId(), user.getId()))
            throw new AccessDeniedException("본인이 등록한 게시글만 삭제할 수 있습니다.");
    }

이러한 예제로 예외가 새로 던져지며 예외가 발생한 메세지를 보내준다.

 

@ExceptionHandler에 등록된 AccessDeniedException을 캐치하여 ExceptionDto라는 객체에 BadRequest의 값이 400과

Httpstatus상태코드 BadRequest400 그리고 "본인이 등록한 게시글만 삭제할 수 있습니다."라는 메세지를 담아 클라이언트에 응답해준다.