1. @ControllerAdvice / @ExceptionHandler
컨트롤러에 @ControllerAdvice 애노테이션을 붙여서 전역 예외 처리 클래스 작성이 가능하다. 매개변수로 패키지 경로를 넣어서 지정된 패키지만 예외처리할 수 있도록 설정이 가능하다.
메서드에 @ExceptionHandler 애노테이션을 붙여서 해당하는 예외에 대한 처리를 할 수 있다.
예외 처리 메서드가 중복된 경우, 예외가 발생한 메서드가 있는 컨트롤러 내의 예외 처리 메서드가 우선이다.
//@ControllerAdvice // 모든 패키지에 처리
@ControllerAdvice("com.fastcampus.ch2") // 지정된 패키지에서 발생한 예외만 처리
public class GlobalCatcher {
@ExceptionHandler(Exception.class)
public String catcher(Exception ex, Model m) {
m.addAttribute("ex", ex);
return "error";
}
// 매개변수에 {}기호를 사용해 여러 예외를 넣을 수 있음
@ExceptionHandler({ NullPointerException.class, FileNotFoundException.class })
public String catcher2(Exception ex, Model m) {
m.addAttribute("ex", ex);
return "error";
}
}
2. @ResponseStatus
@ResponseStatus는 응답 메시지의 상태 코드를 변경할 때 사용한다. (예외 처리 경우 외에도 물론 사용 가능하다.)
< 상태코드 설명 >
401 | Unauthorized |
403 | Forbidden |
404 | Not Found |
405 | Method Now Allowed |
500 | Internal Server Error |
501 | Not Implmented |
503 | Service Unavilable |
첫 번째 경우로, 예외처리 메서드 앞에 붙일 수 있다.
아래 코드에서 @ResponseStatus 애노테이션이 없는 상태라면, NullPointerException 발생 결과 error.jsp 파일로 이동하고 상태코드는 200 (요청 처리 성공) 일 것이다. 에러가 떴는데 상태코드가 200인 상황은 조금 맞지 않다. 따라서 @ResponseStatus 애노테이션을 이용해 Method Not Allowed, 즉 405로 상태코드를 바꿔줄 수 있다.
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) // 405 Method Not Allowed.
@ExceptionHandler({ NullPointerException.class, FileNotFoundException.class })
public String catcher2(Exception ex, Model m) {
m.addAttribute("ex", ex);
return "error";
}
두 번째 경우로는 사용자 정의 예외처리 클래스 앞에 붙일 수 있다.
예외 발생시 에러 처리를 하지 않으면 디폴트 상태코드 값은 500이다. 아래와 같이 애노테이션을 붙여주면 디폴트 값을 바꿀 수 있다.
@ResponseStatus(HttpStatus.BAD_REQUEST) // 400 Bad Request.
class MyException extends RuntimeException {
MyException(String msg) {
super(msg);
}
MyException() {
this("");
}
}
(에러처리 클래스 앞에 붙일 경우 해당 예외철리 클래스 내 예외처리 메서드 실행 시 디폴트 값이 이 값으로 바뀌는 것 같다.)
3. isErrorPage="true"
뷰파일에 <%@ page isErrorPage="true" %>와 같은 옵션을 주면 에러를 보여주기 위한 페이지라는 뜻이다.
그러면 에러처리 메서드에서 아래 사진처럼 Exception ex 를 모델에 담아 보내주지 않아도 뷰파일에서 pageContext.exception 을 이용해 사용할 수 있다.
참고로 true 값을 주면 상태 코드가 강제로 500으로 바뀐다.
4. 사용자 정의 에러처리
RuntimeException 클래스를 상속받은 클래스를 만들어서, 사용자 정의 에러처리 클래스를 만들 수 있다.
class MyException extends RuntimeException {
MyException(String msg) {
super(msg);
}
MyException() {
this("");
}
}
@Controller
public class ExceptionController2 {
@RequestMapping("/ex3")
public String main() throws Exception {
throw new MyException("에러가 발생했습니다");
}
}
5. 에러 페이지 뷰 맵핑
1) 상태 코드별 뷰 맵핑
web.xml 파일 안에 상태 코드별로 연결될 뷰 파일을 지정할 수 있다.
<error-page>
<error-code>400</error-code>
<!-- 위치 = webapp/error400.jsp -->
<location>/error400.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error500.jsp</location>
</error-page>
2) 예외 종류별 뷰 맵핑
servlet-context.xml 파일에 SimpleMappingExceptionResolver를 이용해 예외 종류별 뷰 맵핑을 지정할 수 있다.
<beans:bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<beans:property name="defaultErrorView" value="error" />
<beans:property name="exceptionMappings">
<beans:props>
<!-- key에 있는 부분이 예외 종류 / 태그 내용 error400이 연결 될 에러 뷰(view폴더 안에 있어야 함) -->
<beans:prop key="com.fastcampus.ch2.MyException">error400</beans:prop>
</beans:props>
</beans:property>
<beans:property name="statusCodes">
<beans:props>
<!-- 뷰에 대한(error400) 상태 코드 정의(400) -->
<beans:prop key="error400">400</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
6. 예외 발생시 처리 순서
요청이 오면 DispatcherServlet이 해당 컨트롤러에 넘겨주고, 여기서 예외가 발생하면 다시 DispatcherServlet 으로 넘어간다.
그럼 DispatcherServlet이 예외를 처리하기 위해 예외 처리 전략대로 handlerEceptionResolvers로 등록되어 있는 것들을 순서대로 본다. (1.ExceptionHandlerExceptionResolver / 2.ResponseStatusExceptionResolver / 3.DefaultHandlerExceptionResolver )
먼저 1.ExceptionHandlerExceptionResolver는 우선 같은 컨트롤러 내에 @ExceptionHandler로 등록된 게 있는지 찾고, @ControllerAdvice에서 등록된 게 있는지 찾는다.
못찾으면 2.ResponseStatusExceptionResolver는 @ResponseStatus 애노테이션을 찾아 상태 코드를 변경해주는 일을 한다.
마지막으로 처리를 못하면 3.DefaultHandlerExceptionResolver는 web.xml에서 상태코드에 해당하는 뷰가 있는지 본다.
예외 처리 방법 정리
1. try-catch문으로 처리
2. 컨트롤러에 @ExceptionHandler 메서드로 처리
3. @ControllerAdvice 클래스의 @ExceptionHandler 메서드로 처리
4. SimpleMappingExceptionResolver 이용 - 예외 종류별로 뷰 지정 (servlet-context.xml 파일)
5. 응답 상태 코드별로 뷰 지정 (web.xml 파일)
참조
https://fastcampus.co.kr/dev_academy_nks
스프링의 정석 : 남궁성과 끝까지 간다 | 패스트캠퍼스
국비지원 조기 마감 신화, 베스트셀러 'JAVA의 정석'의 저자 남궁성의 Spring 강의입니다! 오픈톡방과 카페에서 평생 AS를 제공하며 완강과 취업까지 도와드립니다. 지금 할인가로 확인하세요!
fastcampus.co.kr
'3. Back-end > 3-2. Spring MVC - 남궁성' 카테고리의 다른 글
Spring MVC - [ 데이터의 변환 ] (0) | 2023.02.02 |
---|---|
Spring MVC - [ DispatcherServlet ] (0) | 2023.02.01 |
Spring MVC - [ 로그인 시 원래 목적 페이지로 이동 ] (0) | 2023.01.29 |
Spring MVC - [ Session(세션) ] (0) | 2023.01.27 |
Spring MVC - [ Cookie(쿠키) ] (2) | 2023.01.27 |