오봉이와 함께하는 개발 블로그
스프링 MVC 2 - ExceptionResolver Part. 1 본문
API 예외 처리 - 스프링이 제공하는 ExceptionResolver 1
스프링 부트가 기본으로 제공하는 ExceptionResolver
는 다음과 같다.HandlerExceptionResolverComposite
에 다음 순서로 등록
- ExceptionHandlerExceptionResolver
- ResponseStatusExceptionResolver
- DefaultHandlerExceptionResolver -> 우선 순위가 가장 낮다.
ExceptionHandlerExceptionResolver@ExceptionHandler
을 처리한다.
API 예외 처리는 대부분 이 기능으로 해결한다.
따로 자세히 설명한다.
ResponseStatusExceptionResolver
예외가 발생했을 때 HTTP 상태 코드를 지정해준다.
예 : @ResponseStatus(value = HttpStatus.NOT_FOUND)
DefaultHandlerExceptionResolver
스프링 내부 기본 예외를 처리한다.
ResponseStatusExceptionResolver
ResponseStatusExceptionResolver
는 예외에 따라서 HTTP 상태 코드를 지정해주는 역할을 한다.
다음 두 가지 경우를 처리한다.
- @ResponseStatus가 달려있는 예외
- ResponseStatusException 예외
예외에 다음과 같이 @ResponseStatus
어노테이션을 적용하면 HTTP 상태 코드를 변경해준다.
@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "잘못된 요청 오류")
public class BadRequestException extends RuntimeException {
}
BadRequestException
예외가 컨트롤러 밖으로 넘어가면 ResponseStatusExceptionResolver
예외가 해당 어노테이션을 확인해서 오류 코드를 HttpStatus.BAD_REQUEST
(400)으로 변경하고, 메시지도 담는다.
ResponseStatusExceptionResolver
코드를 확인해보면 결국 response.sendError(statusCode, resolvedReason)
를 호출하고 ModelAndView
를 반환한다.sendError(400)
를 호출했기 때문에 WAS에서 다시 오류 페이지(/error
)를 내부 요청한다.
ApiExceptionController - 추가
@GetMapping("/api/response-status-ex1")
public String responseStatusEx1() {
throw new BadRequestException();
}
결과
{
"timestamp": "2022-08-30T16:57:33.081+00:00",
"status": 400,
"error": "Bad Request",
"exception": "hello.exception.exception.BadRequestException",
"path": "/api/response-status-ex1"
}
메시지 기능reason
을 MessageSource
에서 찾는 기능도 제공한다. reason = "error.bad"
ResponseStatusExceptionResolver
에서 MessageSource
에 등록된 메시지를 먼저 검색하고 찾지 못 하면 디폴트 메시지를 사용한다.
@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "error.bad")
public class BadRequestException extends RuntimeException {
}
messages.properties
error.bad=잘못된 요청 오류입니다. 메시지 사용
메시지 사용 결과
{
"timestamp": "2022-08-30T17:03:06.392+00:00",
"status": 400,
"error": "Bad Request",
"exception": "hello.exception.exception.BadRequestException",
"message": "잘못된 요청 오류입니다. 메시지 사용",
"path": "/api/response-status-ex1"
}
ResponseStatusException
@ResponseStatus
는 개발자가 직접 변경할 수 없는 예외(시스템이나 라이브러리가 제공하는 예외)에는 적용할 수 없다.
(어노테이션을 직접 넣어야 하는데, 내가 코드를 수정할 수 없는 라이브러리의 예외 코드 같은 곳에는 적용할 수 없다.)
추가로 어노테이션을 사용하기 때문에 조건에 따라 동적으로 변경하는 것도 어렵다.
이때는 ResponseStatusException
예외를 사용하면 된다.
ApiExceptionController - 추가
@GetMapping("/api/response-status-ex2")
public String responseStatusEx2() {
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "error.bad", new IllegalArgumentException());
}
ResponseStatusException(HttpStatus, resson(에러 메시지), Throwable cause(진짜 발생하는 예외))
결과
{
"timestamp": "2022-08-30T17:09:13.619+00:00",
"status": 404,
"error": "Not Found",
"exception": "org.springframework.web.server.ResponseStatusException",
"message": "잘못된 요청 오류입니다. 메시지 사용",
"path": "/api/response-status-ex2"
}
출처 : 인프런 김영한 지식공유자님 강의 스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
'BE > Spring' 카테고리의 다른 글
스프링 MVC 2 - @ExceptionHandler (0) | 2022.08.31 |
---|---|
스프링 MVC 2 - ExceptionResolver Part. 2 (0) | 2022.08.31 |
스프링 MVC 2 - HandlerExceptionResolver 활용 (0) | 2022.08.31 |
스프링 MVC 2 - HandlerExceptionResolver 시작 (0) | 2022.08.31 |
스프링 MVC 2 - 스프링 부트 기본 오류 처리 (0) | 2022.08.31 |