예외 처리와 오류 페이지
서블릿 예외 처리
- Exception-> WAS까지 예외 전달
- response.sendError(404, "404 오류");
- response.sendError(500);
서블릿 예외 처리 - 오류 화면 제공
//WebServerFactoryCustomizer의 customize구현
ErrorPage errorPage404 = new ErrorPage(HttpStatus.NOT_FOUND, "/error-page/404");
factory.addErrorPages(errorPage404, errorPage500, errorPageEx);
오류 정보 추가
- request.getAttribute(): 예외, 예외 타입, 오류 메시지, 클라이언트 요청 URI,오류가 발생한 서블릿 이름, HTTP 상태 코드 받을 수 있음
서블릿 예외 처리 - 필터
- 예외발생하면 WAS까지 왔다가 다시 컨트롤러 요청 후 view반환->필터나 인터셉트가 한번 더 호출 비효율적
- request.getDispatcherType(): REQUEST, ERROR
- WebConfig: filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST);//기본 값 사용
서블릿 예외 처리 - 인터셉터
- WebConfig: registry.excludePathPatterns( "/error", "/error-page/**" //오류 페이지 경로 뺴기);
스프링 부트 - 오류 페이지
- /error 기본 요청
- BasicErrorController
- 경로에 오류 페이지 파일 만들어 넣기
API 예외 처리
- produces = MediaType.APPLICATION_JSON_VALUE
Map<String, Object> result = new HashMap<>(); Exception ex = (Exception) request.getAttribute(ERROR_EXCEPTION); result.put("status", request.getAttribute(ERROR_STATUS_CODE)); result.put("message", ex.getMessage()); Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); return new ResponseEntity(result, HttpStatus.valueOf(statusCode));
API 예외 처리 - 스프링 부트 기본 오류 처리
- BasicErrorController: errorHtml() , error()
API 예외 처리 - HandlerExceptionResolver
HandlerExceptionResolver: 예외 해결, 동작 방식 변경->정상응답
//MyHandlerExceptionResolver if (ex instanceof IllegalArgumentException) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, ex.getMessage()); return new ModelAndView(); } //WebConfig resolvers.add(new MyHandlerExceptionResolver());
API 예외 처리 - HandlerExceptionResolver 활용
//UserHandlerExceptionResolver-UserException사용
if (ex instanceof UserException) {
String acceptHeader = request.getHeader("accept");
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
if ("application/json".equals(acceptHeader)) {//json
Map<String, Object> errorResult = new HashMap<>();
errorResult.put("ex", ex.getClass());
errorResult.put("message", ex.getMessage());
String result = objectMapper.writeValueAsString(errorResult);
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
response.getWriter().write(result);
return new ModelAndView();
}else{
HTML
}
}
//WebConfig
resolvers.add(new UserHandlerExceptionResolver());
API 예외 처리 - 스프링이 제공하는 ExceptionResolver
- ExceptionHandlerExceptionResolver
- @ExceptionHandler(IllegalArgumentException.class)
- @ExceptionHandler 예외 생략->메서드 파라미터 예외
- ResponseStatusExceptionResolver: HTTP 응답 코드 변경
- @ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "잘못된 요청 오류")
- response.sendError(statusCode, resolvedReason)
- 직접 변경할 수 없는 예외에는 적용x -> ResponseStatusException 사용
- throw new ResponseStatusException(HttpStatus.NOT_FOUND, "error.bad", new IllegalArgumentException());
- DefaultHandlerExceptionResolver : 스프링 내부에서 발생하는 스프링 예외 해결
- TypeMismatchException
- response.sendError(HttpServletResponse.SC_BAD_REQUEST)
API 예외 처리 - @ControllerAdvice
- @ControllerAdvice, @RestControllerAdvice-> 클래스 분리
링크
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2