본문 바로가기
Spring

Spring @RestControllerAdvice 적용

by wadekang 2023. 11. 9.

 

@RestControllerAdvice

@RestControllerAdvice (@ControllerAdvice)는 전역으로 예외 처리할 수 있게 해주는 Annotation

이를 통해 각 Controller 별로 예외 처리 코드를 작성하여 중복 코드가 발생하는 것을 해결할 수 있고, 서비스 코드와 예외 처리 코드를 분리할 수 있음

 

패키지 단위 적용

basePackages에 package 경로를 명시하여 해당 package내에 적용

@Slf4j  
@RestControllerAdvice(basePackages = {"com.example.demo.ctl"}) // 여러개 추가 가능  
public class DemoControllerAdvice {  
  
    @ExceptionHandler  
    public CommonResponse<Object> handler(Exception e) {  
        log.error(e.getMessage(), e);  
  
        CommonResponse<Object> response = new CommonResponse<>();  
        response.setSuccess(false);  
        response.setMessage(e.getMessage());  
  
        return response;  
    }  
}

 

클래스 단위 적용

@Slf4j  
@RestControllerAdvice(assignableTypes = {DemoController.class}) // 여러개 추가 가능
public class DemoControllerAdvice {  
  
    @ExceptionHandler  
    public CommonResponse<Object> handler(Exception e) {  
        log.error(e.getMessage(), e);  
  
        CommonResponse<Object> response = new CommonResponse<>();  
        response.setSuccess(false);  
        response.setMessage(e.getMessage());  
  
        return response;  
    }  
}

 

Exception 별 핸들링

@ExceptionHandler Annotation에 특정 Exception class를 지정하여 해당 Exception을 직접 핸들링 할 수 있음

@Slf4j  
@RestControllerAdvice(basePackages = {"com.example.demo.ctl"})  
public class DemoControllerAdvice {  
  
    @ExceptionHandler  
    public CommonResponse<Object> handler(Exception e) {  
        log.error(e.getMessage(), e);  
  
        CommonResponse<Object> response = new CommonResponse<>();  
        response.setSuccess(false);  
        response.setMessage(e.getMessage());  
  
        return response;  
    }  
  
    @ExceptionHandler(RuntimeException.class)  
    public CommonResponse<Object> handler(RuntimeException e) {  
        log.error(e.getMessage(), e);  
  
        CommonResponse<Object> response = new CommonResponse<>();  
        response.setSuccess(false);  
        response.setMessage("RuntimeException: " + e.getMessage());  
  
        return response;  
    }  
}

 

테스트

다음과 같이 요청을 보내면 RuntimeException을 발생시키는 API가 있다고 가정

@PostMapping("/exception")  
public CommonResponse<Object> exception() {  
    throw new RuntimeException("exception");  
}

 

@RestControllerAdvice를 적용하지 않은 상태에서 요청을 보내보면 다음과 같이 응답이 오는 것을 확인할 수 있음

{
  "timestamp": "2023-11-09T07:54:24.266+00:00",
  "status": 500,
  "error": "Internal Server Error",
  "path": "/exception"
}

 

@RestControllerAdvice를 적용한 후 다시 요청을 보내면 응답은 다음과 같음

{
  "success": false,
  "message": "RuntimeException: exception",
  "data": null
}

 

RuntimeException.class를 적용한 ExceptionHandler가 적용되어 message가 "RuntimeException: exception"으로 반환된 것을 볼 수 있음

 

댓글