티스토리 뷰

Spring Exception Handler

안녕하세요.

오늘은 스프링 부트를 사용하면서

Exception처리를 하는 방법에 대해 공유해보도록 하겠습니다.


@ExceptionHandler

첫 번째는 @ExceptionHandler를 사용해서 Error를 처리하는 방법입니다.

우선 프로젝트를 하나 만들어줍니다.

프로젝트 만들기

  • IndexController.java

      @RestController
      public class IndexController {
    
          @GetMapping
          public ResponseEntity index() {
              return ResponseEntity.ok("Hello ExceptionHandler Example");
          }
      }

ResponseEntity를 반환하는 간단한 API입니다.

  • @RestContoller view가 아닌 json형태의 객체 데이터를 반환하는 Controller임을 명시

서버를 실행해보면

위 코드에서 반환한 텍스트가 출력되게 됩니다.

만약, 특정 게시물을 찾는 API에서 NotFoundException을 발생시키고 싶다면

아래와 같은 코드를 하나씩 작성해보겠습니다.

  • NotFoundException.java

      public class NotFoundException extends RuntimeException {
    
          public final static int INDEX_NOT_FOUND = 101;
          public final static int BOARD_NOT_FOUND = 201;
    
          private final int code;
    
          public int getCode() {
              return code;
          }
    
          public NotFoundException(int code) {
              this.code = code;
          }
    
          public NotFoundException(int code, String message) {
              super(message);
              this.code = code;
          }
      }

    NotFoundException 클래스는 RuntimeException을 상속받고 code라는 멤버 변수를 가지고 있습니다.

    생성자를 통해 code를 셋팅할 수 있게 만들어줬습니다.

    또한 Message도 받을 수 있는 생성자도 만들어 줍니다.

  • ErrorCode.java

      public enum ErrorCode {
    
          INDEX_NOT_FOUND(1001, "인덱스가 존재하지 않습니다."),
          BOARD_NOT_FOUND(1002, "게시글을 찾을 수 없습니다.");
    
          private int errorCode;
          private String errorMessage;
    
          public String getErrorMessage() {
              return errorMessage;
          }
    
          public int getErrorCode() {
              return errorCode;
          }
    
          ErrorCode(int errorCode, String errorMessage) {
              this.errorCode = errorCode;
              this.errorMessage = errorMessage;
          }
      }

    에러코드를 Enum으로 관리하기 위한 클래스도 만들어줍니다.

    필요한 에러코드는 위에 처럼 추가해서 관리할 수 있습니다.

    이렇게 하게 되면 좀 더 체계적으로 에러코드를 관리할 수 있을 거 같습니다.

  • IndexController.java

              ...
              ...
    
              @GetMapping("nfe")
          public ResponseEntity notFound() {
              throw new NotFoundException(ErrorCode.INDEX_NOT_FOUND.getErrorCode(), ErrorCode.INDEX_NOT_FOUND.getErrorMessage());
          }
    
          @ExceptionHandler(NotFoundException.class)
          public ResponseEntity<ErrorResult> notFoundException(NotFoundException e) {
    
                      ErrorResult er = new ErrorResult();
              er.setCode(e.getCode());
              er.setStatus(HttpStatus.NOT_FOUND);
              er.setMessage(e.getMessage());
    
              return ResponseEntity.status(HttpStatus.NOT_FOUND).body(er);
          }

    /nfe라는 엔드포인트를 가진 API를 만들고 NotFoundException을 발생하게 합니다.

    그때 위에서 만든 ErrorCode 클래스에서 errorCodeerrorMessage를 넣어줍니다.

    그리고 아래에 @ExceptionHandler 어노테이션을 가진 메서드를 만들어줍니다.

    그러면 저 메소드를 가진 클래스에서 발생하는 NotFoundException은 저 메서드에서 처리하게 됩니다.

        이제 서버를 실행한 후 /nfe를 호출해봅니다.

위 결과와 같이 NotFoundException을 처리할 수 있게 됩니다.

그렇다면 모든 클래스마다 @ExceptionHadler를 중복해서 만들어야 할까요?


@ControllerAdvice

여러 클래스의 Exception을 처리할 수 있는 @ControllerAdvice

클래스를 하나 만들어보겠습니다.

  • NotFoundExceptionAdvice.java

      @RestControllerAdvice
      public class NotFoundExceptionAdvice {
    
          @ExceptionHandler(NotFoundException.class)
          public ResponseEntity<ErrorResult> notFoundException(NotFoundException e) {
              ErrorResult er = new ErrorResult();
              er.setCode(e.getCode());
              er.setStatus(HttpStatus.NOT_FOUND);
              er.setMessage(e.getMessage());
    
              return ResponseEntity.status(HttpStatus.NOT_FOUND).body(er);
          }
      }

    위에 만든 클래스는 이제 여러 Controller에서 발생하는 NotFoundException을 처리하게 됩니다.

  • BoardController.java

      @RestController
      public class BoardController {
    
          @GetMapping("/board")
          public ResponseEntity<String> board() {
              throw new NotFoundException(ErrorCode.BOARD_NOT_FOUND.getErrorCode(), ErrorCode.BOARD_NOT_FOUND.getErrorMessage());
          }
      }

    BoardController@ExceptionHandler 메서드를 가지고 있지 않습니다.

    그래도 NotFoundExceptionAdvice 클래스가 에러를 처리해줄 겁니다.

호출해보기

localhost:8080/board

결과를 보면 에러가 잘 처리된 것을 볼 수 있습니다.


@ExceptionHandler@ControllerAdvice를 활용하여

Exception을 처리하는 방법을 공유해봤습니다.

 

더 좋은 방법과 피드백 있다면 댓글로 알려주시면 감사하겠습니다.


소스코드는 깃 헙에서 확인하실 수 있습니다.

alxndrDev/Study

'Dev > Spring' 카테고리의 다른 글

Spring @EventListner 사용해보기 - 2  (0) 2020.11.22
Spring @EventListner 사용해보기  (0) 2020.11.18
Spring Web Static Resources  (0) 2020.11.11
Spring boot 프로젝트 만들기  (0) 2020.10.21
Spring에서 RestTemplate로 API 호출하기  (0) 2020.09.01
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함