Henu
개발냥발
Henu
전체 방문자
오늘
어제
  • 분류 전체보기 (411)
    • DevOps (52)
      • Kubernetes (19)
      • Docker (14)
      • AWS (3)
      • Nginx (4)
      • Linux (4)
      • ArgoCD (1)
      • CN (2)
      • NATS (0)
      • Git (5)
    • Back-End (30)
      • Django (18)
      • Spring (5)
      • JPA (1)
      • MSA (5)
    • CS (87)
      • SystemSoftware (20)
      • OS (25)
      • Computer Architecture (16)
      • Network (23)
      • Database (2)
    • Lang (21)
      • Java (9)
      • Python (4)
      • C# (8)
    • Life (12)
    • 블록체인 (2)
    • Algorithm (204)
      • BOJ (160)
      • 프로그래머스 (19)
      • LeetCode (4)
      • SWEA (1)
      • 알고리즘 문제 해결 전략 (8)
      • DS, algorithms (7)
      • Checkio (5)
    • IT (2)

블로그 메뉴

  • GitHub
  • 글쓰기
  • 관리자

공지사항

  • Free!

인기 글

태그

  • 다이나믹 프로그래밍
  • BFS
  • 프로그래머스
  • boj
  • DFS
  • Network
  • django
  • docker
  • 백트래킹
  • Kubernetes

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Henu

개발냥발

Back-End/Spring

[Spring] 전역 REST 컨트롤러 예외 핸들러 만들기

2022. 5. 2. 16:32

 

 

예외 처리를 REST 컨트롤러의 비즈니스 로직, 즉 API 구현부분과 분리하기 위해 @RestControllerAdvice 를 사용할 수 있다.

 

@RestControllerAdvice

@ControllerAdvice 와 @ResponseBody 가 합쳐진 어노테이션이다.

 

@ResponseBody는 컨트롤러의 return 값으로 객체를 넘길 경우 Json으로 변환해주는 어노테이션이다.

 

@ControllerAdvice는 아래 설명을 참고할 수 있다.

 

@ControllerAdvice

 

@ExceptionHandler, @ModelAttribute, @InitBinder 가 적용된 메서드들을 AOP를 적용해
컨트롤러에 적용하기 위해 만들어진 어노테이션이다.

 

  • basePackageClasses, basePackage 를 지정해서 어노테이션이 적용될 패키지 범위를 적용할 수 있다.
  • annotations에 class 를 지정해주면 클래스 단위로 범위를 적용할 수 있다.
  • 아무것도 설정해주지 않으면 전역으로 작동한다.

 

HTTP 프로토콜에 대한 에러 정보를 일관성있게 전달하는것이 좋다.

따라서 HttpErrorInfo 와 같은 클래스를 생성해서 ErrorResponse 처리에 사용할 수 있다.

@Getter
public class HttpErrorInfo {
    private final ZonedDateTime timestamp;
    private final String path;
    private final HttpStatus httpStatus;
    private final String message;

    public HttpErrorInfo(HttpStatus httpStatus, String path, String message) {
        timestamp = ZonedDateTime.now();
        this.httpStatus = httpStatus;
        this.path = path;
        this.message = message;
    }
}

 

HttpErrorInfo 는 다음과 같은 정보를 가지고 있다.

  • 현재 시간
  • Error가 발생한 request의 path
  • 에러 코드(Http status)
  • 에러 메시지

 

 

이제 RuntimeException 을 implement 하는 커스텀 예외 처리를 생성할 수 있다.

DB 에서 데이터를 조회했을 때 데이터가 없는 경우에 출력할 에러(NotFoundException)를 생성한다.

public class NotFoundException extends RuntimeException {
    public NotFoundException() {
    }

    public NotFoundException(String message) {
        super(message);
    }

    public NotFoundException(String message, Throwable cause) {
        super(message, cause);
    }

    public NotFoundException(Throwable cause) {
        super(cause);
    }
}

 

 

 

프로젝트 전역에 적용될 GlobalControllerExceptionHandler 를 생성한다.

@RestControllerAdvice
class GlobalControllerExceptionHandler {

    @ResponseStatus(NOT_FOUND)
    @ExceptionHandler(NotFoundException.class)
    public @ResponseBody
    HttpErrorInfo handleNotFoundExceptions(ServerHttpRequest request, Exception ex) {

        return createHttpErrorInfo(NOT_FOUND, request, ex);
    }
    
    private HttpErrorInfo createHttpErrorInfo(HttpStatus httpStatus, ServerHttpRequest request, Exception ex) {
        final String path = request.getPath().pathWithinApplication().value();
        final String message = ex.getMessage();

        LOG.debug("Returning HTTP status: {} for path: {}, message: {}", httpStatus, path, message);
        return new HttpErrorInfo(httpStatus, path, message);
    }
}

 

클래스 내부의 handleNotFoundExceptions 메서드

  • @ResponseStatus는 NOT_FOUND로 지정해준다.
  • ExceptionHandler의 적용 클래스를 위에서 만들었던 NotFoundException 으로 지정해준다.

 

throw new NotFoundException("message")


위와 같이 적절한 에러를 throw 하면 GlobalHandler에서 에러를 발견하고 우리가 원하는 형식으로 Response를 넘겨줄 수 있다.

 

'Back-End > Spring' 카테고리의 다른 글

[Spring] 멀티모듈 단일 프로젝트 구성하기 (gradle)  (0) 2022.06.05
[spring] SpringBoot mongodb 인덱싱 안되는 문제 (SpringBoot mongodb Unique index not created)  (0) 2022.05.11
[Spring] mongoDB Test Error (Error creating bean with name 'embeddedMongoServer' defined in class path resource)  (0) 2022.05.10
[Spring] Gradle dependencies 정리  (0) 2022.05.07
    'Back-End/Spring' 카테고리의 다른 글
    • [Spring] 멀티모듈 단일 프로젝트 구성하기 (gradle)
    • [spring] SpringBoot mongodb 인덱싱 안되는 문제 (SpringBoot mongodb Unique index not created)
    • [Spring] mongoDB Test Error (Error creating bean with name 'embeddedMongoServer' defined in class path resource)
    • [Spring] Gradle dependencies 정리

    티스토리툴바