시작#
HTML은, 오류가 나면 4xx,5xx 오류 페이지만 있으면 된다. 근데, API의 경우에는 각 오류 상황에 맞는 응답 스펙을 정하고, json으로 줘야됨
ex)
@RequestMapping(value="/error-page/500",produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Map<String, Object>> errorPage500Api(HttpServletRequest request , HttpServletResponse response){
Map<String, Object> result = new HashMap<>();
Exception ex = (Exception) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
result.put("status",request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE));
result.put("message", ex.getMessage());
Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
return new ResponseEntity<>(result, HttpStatus.valueOf(statusCode));
}요청의 Accept가 application/json인 경우를 처리
HttpRequest의 정보를 토대로 json 생성 후 반환
이전글 참고
API 처리시 가장 좋은 방법은 ExceptionHandler 사용이다
HandlerExceptionResolver#
발생하는 예외에 따라서 각각 처리하고 싶다면?
- ex)
IllegalArgumentEsxeption을 처리하지 못하면,400으로 처리하고싶음
HandlerExceptionResolver
컨트롤러 밖으로 던져진 예외를 해결하고, 동작 방식을 변경
Was가 에러 페이지를 찾아서 다시 제공하지 않고, 정상응답
줄여서 ExceptionResolver


스프링 부트가 제공하는 ExceptionReoslver#
ExceptionHandlerExceptionResolver(가장 중요하므로 따로다룸)ResponseStatusExceptionResolverDefaultHandlerExceptionResolver(마지막우선순위)
ResponseStatusExceptionResolver
예외에 따라서 HTTP 코드 지정
내부적으로 response.sendError()호출
ex) @responseStatus가 달려있는 예외 또는 ResponseStatusException
@ResponseStatus(code= HttpStatus.BAD_REQUEST,reason = "잘못된 요청 오류")
public class BadRequestException extends RuntimeException{}**DefaultHandlerExceprtionResolver **
스프링 내부 예외 해결 (TypeMismatchException 등)
내부적으로 response.sendError()호출
@ExceptionHandler#
ExceptionHandlerExceptionResolver 사용
우선순위도 가장 높고, 실무에서 API 예외 처리 시 거의 이것만 사용
@ExceptionHandler어노테이션을 선언하고, 예외를 지정해주면 해당 컨틀롤러에서 해당 예외(자식도)가 발생하면 이 메서드가 호출됨. (컨트롤러와 비슷하게 동작함)
ex)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(IllegalArgumentException.class)
public ErrorResult illegalExHandler(IllegalArgumentException e){
log.error("[exceptionHandler] ex",e);
return new ErrorResult("BAD",e.getMessage());
}스프링의 우선순위는 항상 자세한 것이 우선권을 가짐 공식문서
@ControllerAdvice#
정상 처리와 예외 처리 코드를 분리
- 대상으로 지정한 여러 컨트롤러에
@ExceptionHandler,@InitBuilder부여해줌 - 컨트롤러, 패키지를 직접 지정 가능 (지정안하면 전부)