HTML 페이지 vs API 오류
- HTML 페이지
- BasicErrorController 는 HTML 페이지를 제공하는 경우에는 매우 편리 (4xx, 5xx)
- API 오류
- API 마다, 각각의 컨트롤러나 예외마다 서로 다른 응답 결과를 출력해야 할 수 있음
- API 오류 처리는 뒤에서 설명할 @ExceptionHandler 를 사용
스프링 부트가 기본으로 제공하는 ExceptionResolver
- ExceptionHandlerExceptionResolver
- @ExceptionHandler 을 처리
- API 예외 처리는 대부분 이 기능으로 해결
- ResponseStatusExceptionResolver
- HTTP 상태 코드를 지정
- @ResponseStatus 가 달려있는 예외 처리 (@ResponseStatus(value = HttpStatus.NOT_FOUND))
- ResponseStatusException 예외 처리
- HTTP 상태 코드를 지정
- DefaultHandlerExceptionResolver
- 스프링 내부 기본 예외 처리
- 우선 순위가 가장 낮음
ResponseStatusException
- @ResponseStatus는 개발자가 직접 변경할 수 없는 예외에는 적용할 수 없음
// Controller
@GetMapping("/api/response-status-ex1")
public String responseStatusEx1() {
throw new BadRequestException();
}
// BadRequestException.class
@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "error.bad")
public class BadRequestException extends RuntimeException{
}
- 조건에 따라 동적으로 변경→ ResponseStatusException 예외를 사용
// Controller
@GetMapping("/api/response-status-ex2")
public String responseStatusEx2() {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "error.bad", new IllegalArgumentException());
}
DefaultHandlerExceptionResolver
- 스프링 내부에서 발생하는 스프링 예외를 해결
- ex) 파라미터 바인딩 시점에 타입이 맞지 않으면 내부에서 TypeMismatchException이 발생하는 것
- 이것을 500 오류가 아니라 HTTP 상태 코드 400 오류로 변경하는 역할을 함
// Controller
@GetMapping("/api/default-handler-ex2")
public String defaultException(@RequestParam Integer data) {
return "ok";
}
ExceptionHandlerExceptionResolver
- @ExceptionHandler 애노테이션을 선언하고, 해당 컨트롤러에서 처리하고 싶은 예외를 지정
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class)
public ErrorResult illegalExHandler(IllegalArgumentException e) {
log.error("[exceptionHandler] ex", e);
return new ErrorResult("BAD", e.getMessage());
}
@ExceptionHandler
public ResponseEntity<ErrorResult> userExHandler(UserException e) {
log.error("[exceptionHandler] ex", e);
ErrorResult errorResult = new ErrorResult("USER-EX", e.getMessage());
return new ResponseEntity(errorResult, HttpStatus.BAD_REQUEST);
}
@ControllerAdvice
- 정상 코드와 예외 처리 코드 분리
- @ControllerAdvice는 대상으로 지정한 여러 컨트롤러에 @ExceptionHandler, @InitBinder 기능을 부여해주는 역할
- @ControllerAdvice에 대상을 지정하지 않으면 모든 컨트롤러에 적용됨 (글로벌 적용)
@Slf4j
@RestControllerAdvice
public class ExControllerAdvice {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class)
public ErrorResult illegalExHandler(IllegalArgumentException e) {
log.error("[exceptionHandler] ex", e);
return new ErrorResult("BAD", e.getMessage());
}
}
참고 강의:
스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 인프런 | 강의
웹 애플리케이션 개발에 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. MVC 2편에서는 MVC 1편의 핵심 원리와 구조 위에 실무 웹 개발에 필요한 모든 활용 기술들을 학습할 수 있
www.inflearn.com
'Spring Boot' 카테고리의 다른 글
JUnit과 Mockito 기반의 Spring 단위 테스트 코드 작성 방법 (1) | 2023.08.20 |
---|---|
단위 테스트(Unit Test)와 통합 테스트 (0) | 2023.08.20 |
서블릿 필터, 스프링 인터셉터 (0) | 2023.07.10 |
쿠키, 세션 - 스프링 적용 (0) | 2023.07.10 |
Validation (0) | 2023.07.05 |