컨트롤러 메서드 내에서 try-catch
@ExceptionHandler
- 컨트롤러 내부에서 예외를 처리하고 싶은 경우
- 컨트롤러 내부의 메서드들에서 예외가 발생했을 때 처리 과정이 중복된다면, 그 예외를 처리할 메서드를 컨트롤러 내부에 작성하고
메서드에 @ExceptionHandler({처리할 예외}) 를 붙인다
@ControllerAdvice
- 여러 컨트롤러에서 발생하는 예외를 처리하고 싶을 경우
- 예외를 처리하는 클래스를 따로 만들고 클래스에 @ControllerAdvice 를 붙이면 모든 패키지의 컨트롤러의 예외를 처리할 수 있다(전역 예외 처리 클래스)
- @ControllerAdvice("..") 안에 패키지 명을 적으면 해당 패키지의 컨트롤러의 예외를 처리할 수 있다
- 만약 컨트롤러에서 예외가 발생했을 때 같은 클래스 내부에 예외 처리가 있다면, 외부에 예외 처리 클래스가 있더라도 같은 클래스의 예외 처리를 통해 예외 처리를 한다
- 예외처리가 중복될 경우 가까운 곳에서 처리
@ResponseStatus
- @ResponseStatus(HttpStatus.설정할에러)
1. 예외처리 메서드에서
- 메서드에 붙인다
- 응답 메세지의 상태 코드를 변경할 때 사용
- 예외를 처리하고 jsp 뷰를 반환하면, 브라우저에는 200번대 상태 코드가 나온다(요청 성공)
- 예외가 났는데 요청 성공 상태인 것이 이상하기 때문에 예외의 상태코드로 변경해준다
- 예외 처리 메서드마다 다른 코드를 붙일 수 있다
2. 사용자 정의 예외클래스에서
- 클래스에 붙인다
- 예외클래스는 상태코드가 default 500
- 다른 걸로 바꾸고 싶을 때 바꿀 수 있음
Error를 보여주는 View
- 모델로 예외 객체를 뷰에 가져와서 보여줄 수 있지만 그럴 필요가 없다
- 기본 객체 pageContext.exception을 사용할 수 있다
- web.xml에 에러 코드에 따른 에러 페이지를 지정할 수 있다(코드별로 만들 수 ㅣ있음)
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<error-page>
<error-code>400</error-code>
<location>/error400.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error500.jsp</location>
</error-page>
400번 에러가 나면 error400.jsp를, 500번 에러가 나면 error500.jsp를 에러메세지 대신에 보여준다
SimpleMappingExceptionResolver
- 예외 종류별 뷰 맵핑에 사용
- servlet-context.xml에 등록
<beans:bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<beans:property name="defaultErrorView" value="error"/>
<beans:property name="exceptionMappings">
<beans:props>
<beans:prop key="com.fastcampus.ch2.MyException">error400</beans:prop>
// 이런 예외가 발생하면 이 뷰를 보여줘라. 예외 종류와 뷰를 연결
</beans:props>
</beans:property>
<beans:property name="statusCodes">
<beans:props>
<beans:prop key="error400">400</beans:prop>
//error400 뷰를 보여줄 때 상태 코드를 400로 해라
(뷰에서 isErrorPage를 false로 바꿔야 지정한 코드로 나옴, 안그러면 기본값인 500으로 나옴)
</beans:props>
</beans:property>
</beans:bean>
ExceptionResolver
- 클라이언트가 요청을 보내면 DispatcherServlet이 받아서 해당 컨트롤러에 넘겨준다
- 컨트롤러에서 예외가 발생하면 throw로 자신을 호출한 쪽으로 예외를 넘긴다
- 호출한 쪽인 DispatcherServlet이 예외를 받고 예외를 처리할 수 있는 ExceptionResolver가 있는지 HandlerExceptionResolvers를 본다
- 1번인 ExceptionHandler 항목에 해당하는 예외처리를 찾으면 해당 Handler가 예외를 처리한다
- 못 찾으면 2번으로 넘어간다.
ResponseStatus 항목에 해당하는 예외 처리를 찾으면 예외 상태 코드를 변경해주고 변경한 상태코드에 해당하는 뷰를 보여준다
- 2번까지 처리를 못하면 마지막으로 스프링에 정의된 예외의 상태코드(500)를 400이나 500으로 바꿔주는 DefaultHandler가 처리한다