Spring Boot Web의 여러가지 기능-(3)

개발세발·2024년 1월 22일

Spring Boot의 예외처리

    1. Request-> 2. Filter-> 3. DispatcherServlet(Handler Mapping을 통해 어떠한 주소를 가진 컨트롤러로 매칭할 지 결정)-> 4. (매칭이 되면)Controller-Service-DB(응답-response을 내림)-> Client에게 전달.
  • But, 4번에서 처리 과정 중 예외가 발생하면 Exception Handler를 통해 예외에 대한 응답을 내려줌.

@Slf4j
@RestController
@RequestMapping("/api")
public class ExceptionRestAPIController {
    @GetMapping(path = "")
    public void exception(){
        var list = List.of("hello");

        var element = list.get(1);

        log.info("element: {}", element);
    }
}
  • Index에러 발생시켰음.
  • try-catch로 에러 하나하나 설정하는 것은 비효율적인 방법. -> 글로벌한 처리를 위해 ExceptionHandler를 사용.
@Slf4j
@RestControllerAdvice(basePackageClasses = {ExceptionRestAPIBController.class, ExceptionRestAPIController.class}) //RestAPI가 사용하는 곳의 예외를 감지, 모든 예외를 잡아주는 글로벌한 컨트롤러 예외 핸들러
@Order(1)
public class RestAPIExceptionHandler {

    @ExceptionHandler(value = {Exception.class})
    public ResponseEntity exception(Exception exception){
        log.error("RestAPIExceptionHandler", exception);
        return ResponseEntity.status(200).build();
    }

    @ExceptionHandler(value = {IndexOutOfBoundsException.class}) //value에는 잡고 싶은 오류를 입력
    public ResponseEntity outOfBound(
            IndexOutOfBoundsException exception
    ){
        log.error("IndexOutOfBoundsException", exception);
        return ResponseEntity.status(200).build();
    }

    @ExceptionHandler(value = {NoSuchElementException.class})
    public ResponseEntity<API> noSuchElement(
            NoSuchElementException exception
    ){
        log.info("", exception);
        var reponse =  API.builder()
                .resultCode(String.valueOf(HttpStatus.NOT_FOUND.value()))
                .resultMessage(HttpStatus.NOT_FOUND.getReasonPhrase())
                .build();
        return ResponseEntity
                .status(HttpStatus.NOT_FOUND)
                .body(reponse);
    }

}
  • @RestControllerAdvice를 통해 RestAPI를 사용하는 곳에서 발생하는 Exception을 감지.

  • @ExceptionHandler를 통해 예외를 감지하고 (value = {Exception.class})로 글로벌하게 모든 예외를 잡아준다.

  • 명시적으로 예외를 감지하려면 @ExceptionHandler(value = {IndexOutOfBoundsException.class}) 등의 방식으로 하면 됨.

 @ExceptionHandler(value = {NumberFormatException.class})
    public ResponseEntity numberFormatException(
            NumberFormatException numberFormatException
    ){
        log.error("RestAPIBController: {}", numberFormatException);
        return ResponseEntity.ok().build();
    }
  • @ExceptionHandler(value = {NumberFormatException.class})을 통해서 위에 있던 Advice로 예외처리가 넘어가지 않고 NumberFormatException에 대해서는 아래 클래스로 처리하겠다고 지정할 수 있음.

  • 그러나 해당 방법보다 ExceptionHandler를 만들고, @RestControllerAdvice(basePackageClasses = {ExceptionRestAPIBController.class, ExceptionRestAPIController.class}) 를 사용하여 특정 컨트롤러에 대한 예외를 처리하도록 지정해줄 수 있음.

0개의 댓글