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 사용이다
발생하는 예외에 따라서 각각 처리하고 싶다면?
IllegalArgumentEsxeption을 처리하지 못하면, 400으로 처리하고싶음HandlerExceptionResolver
컨트롤러 밖으로 던져진 예외를 해결하고, 동작 방식을 변경
Was가 에러 페이지를 찾아서 다시 제공하지 않고, 정상응답
줄여서 ExceptionResolver


ExceptionReoslverExceptionHandlerExceptionResolver (가장 중요하므로 따로다룸)
ResponseStatusExceptionResolver
DefaultHandlerExceptionResolver (마지막우선순위)
ResponseStatusExceptionResolver
예외에 따라서 HTTP 코드 지정
내부적으로 response.sendError()호출
ex) @responseStatus가 달려있는 예외 또는 ResponseStatusException
@ResponseStatus(code= HttpStatus.BAD_REQUEST,reason = "잘못된 요청 오류")
public class BadRequestException extends RuntimeException{}
DefaultHandlerExceprtionResolver
스프링 내부 예외 해결 (TypeMismatchException 등)
내부적으로 response.sendError()호출
@ExceptionHandlerExceptionHandlerExceptionResolver 사용
우선순위도 가장 높고, 실무에서 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 부여해줌