SpringBoot를 사용하여 공부하면서 생각해보니 예외처리에 대한 로직을 따로 찾아보거나 한적이 없어서 한번 찾아보려고 한다.
유튜브에 예외처리 강의가 있어 참고하였다.
스프링 부트의 예외처리 방식은 크게 2가지가 존재한다.
- @ControllerAdvice(@RestControllerAdvice)를 통한 모든 Controller에서 발생할 수 있는 예외처리
- @ExceptionHandler를 통한 특정 Controller의 예외처리
근데 각컨트롤러 마다 예외처리 메소드를 따로두면.. 딱히 효율적일 것 같진 않다는 생각이 든다.
다음은 예시다.
1번케이스에 대한 예시이다.
@RestControllerAdvice
@Slf4j
public class ExceptionController {
@ExceptionHandler(value = Exception.class)
public ResponseEntity<Map<String,String>> ExcetionHandler(Exception e){
log.info("전역 컨트롤러에서 예외처리");
HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
Map<String,String> resultMap = new HashMap<>();
resultMap.put("error type", httpStatus.getReasonPhrase());
resultMap.put("code","400");
resultMap.put("message","에러발생");
return ResponseEntity.status(httpStatus).body(resultMap);
}
@ExceptionHandler(value = NullPointerException.class)
public String nullHandler(Exception e){
return "null";
}
}
@PostMapping("/exception")
public void exceptionTest() throws Exception {
throw new Exception();
}
post방식으로 예외를 발생시키는 요청을 하나 추가한 후 포스트맨으로 요청을 날려보았다.
{
"code": "400",
"error type": "Bad Request",
"message": "에러발생"
}
오류가 나지 않고 포스트맨에 해당 json형태의 오류 속성들이 리턴되었다.
그렇다면 해당 오류를 처리하는 ExceptionHandler를 요청하는컨트롤러 내부 메소드에도 작성한다면 어떻게될까 테스트해본다.
@ExceptionHandler(value = Exception.class)
public ResponseEntity<Map<String,String>> ExcetionHandler(Exception e){
log.info("지역 컨트롤러에서 예외처리");
HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
Map<String,String> resultMap = new HashMap<>();
resultMap.put("error type", httpStatus.getReasonPhrase());
resultMap.put("code","400");
resultMap.put("message","에러발생");
return ResponseEntity.status(httpStatus).body(resultMap);
}
콘솔에 찍힌 로그에서 지역 컨트롤러에서 선언된 핸들러를 탄것을 확인 할 수 있다.
즉 동일 예외(예제에선 Exception.class)에선 컨트롤러 내부에서 선언된 핸들러가 우선순위를 갖는다.
여기서 @ControllerAdvice는 빈으로 관리되기도 한다고 한다. 또한 주의할 점은, 프로젝트에 하나의 @ControllerAdvice만 관리하는 것을 권장한다고 한다. 여러 개를 사용하려면, basePackageClasses 및 basePackages와 같은 Selector를 사용해야하기 때문인데 이렇게 되면, OR연산을 통해 올바른 Selector를 찾아야한다. 해당 과정은 런타임 시점에 수행되므로, 많아질 수록 성능에 영향을 미치고 복잡성이 올라갈 수 있다.
'Spring' 카테고리의 다른 글
Redis와 SpringBoot 연동 (1) | 2023.11.20 |
---|---|
@Conditional과 @AutoConfiguration (0) | 2023.11.06 |
SpringBoot AutoConfiguration (0) | 2023.11.06 |
SpringBoot와 웹서버 (0) | 2023.10.31 |
인터셉터 설정 (0) | 2023.10.05 |