Controller를 작성할 때 예외 상황을 고려하면 처리해야 하는 작업이 엄청나게 늘어날 수 밖에 없다. 154p
스프링 MVC에서는 이러한 작업을 다음과 같은 방식으로 처리할 수 있다.
1) @ControllerAdvice와 @ExceptionHandler를 이용한 처리
@ControllerAdvice를 선언하면 웹어플리케이션의 특정 익셉션들을 공통적으로 핸들링 할 수 있다.
@ControllerAdvice는 뒤에서 배우게 되는 AOP(Aspect-Oriented-Prograinming)를 이
용하는 방식이다. AOP에 대해서는 별도의 파트에서 설명하겠지만, 간단히 언급하자면
핵심적인 로직은 아니지만 프로그램에서 필요한 '공통적인 관심사(cross-concern)는 분
리’하자는 개념이다. Controller를 작성할 때는 메서드의 모든 예외사항을 전부 핸들
링해야 한다면 중복적이고 많은 양의 코드를 작성해야 하지만, AOP 방식을 이용하면 공
통적인 예외사항에 대해서는 별도로 @ControllerAdvice를 이용해서 분리하는 방식이다.
@ControllerAdvice는 해당 객체가 스프링의 컨트롤러에서 발생하는 예외를 처리하는 존재임을
명시하는 용도로 사용하고,
@ExceptionHandler는 해당 메서드의 예외 타입을 처리한다는 것을 의미.
예 :
@ExceptionHandler(Exception.class)
public String except(Exception ex, Model model) {
}
Exception.class를 지정하였으므로 모든예외에 대한 처리가 except() 메서드만을 이용해서 처리할 수 있다
만일 특정한 타입의 예외를 다루고 싶다면 Exception.class 대신에 구체적인 예외의 클
래스를 지정해야 한다
2) 404에러페이지
WAS의 구동 중 가장 흔한 에러와 관련된 HTTP 상태 코드는 ’404’와 ’500’ 에러 코드다.
500 메시지는 'Internal Server Error’이므로 @ExceptionHandler를 이용해서
처리되지만, 잘못된 URL을 호출할 때 보이는 404 에러 메시지의 경우는 조금 다르게 처
리하는 것이 좋다. 서블릿이나 JSP를 이용했던 개발 시에는 web.xml을 이용해서 별도의 에러 페
이지를 지정할 수 있다. 하지만 에러 발생 시 추가적인 작업을 하기는 어렵기 때문에 스프링을 이
용해서 404와 같이 WAS 내부에서 발생하는 에러를 처리하는 방식을 알아두는 것이 좋다.
스프링 MVC의 모든 요청은 DispatcherServlet을 이용해서 처리되므로 404 에러도 같
이 처리할 수 있도록 web.xml을 수정해야한다.
왜냐하면 잘못된 URL을 호출할 때 DispatcherServlet을 이용해처 바로 처리를 하면
예외 처리기를 호출하지 않고 오류 응답을 보내는것 같다.
즉, 서블릿의 404 에러처럼 DispatcherServlet에서 바로 처리해버리는 익셉션들의 경우는
@ControllerAdvice 까지 전달되지 않고 그 전에 DispatcherServlet에 의해 처리된다.
그래서 보통은 404 에러 페이지가 뜨게 된다.
그래서 web.xml을 수정해야한다.
<init-param>
<param-name>throwExceptionIfNoHandlerFound</param-name>
<param-value>true</param-value>
</init-param>
404 에러 처리를 위해 404에러 페이지로 넘기지 않고,익셉션을 발생 시키는 설정
이렇게 설정을 추가해주면 이제 @ControllerAdvice에서 에러 핸들링을 해줄수 있다.
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handle404(NoHandlerFoundException ex) {
return "error/404errorPage";
}
웹개발자를 위한 스프링 4.0 349페이지
1) @ExceptionHandler을 이용한 익셉션 처리
컨트롤러 클래스에 @ExceptionHandler을 적용하면 해당 컨트롤러에서 발
생한 익셉션만을 처리한다.
스프링 MVC는 컨트롤러에서 익셉션이 발생하면 HandlerExceptionResolver에 처
리를 위임한다. HandlerExceptionResolver에는 여러 종류가 존재하는데
MVC 설정 mvc:annotation-driven 태그나 @EnableWebMvc 애노테이션을 사용할 경
우 내부적으로 ExceptionHandlerExceptionResolver를 등록한다. 이 클래스는
@ExceptionHandler 애노테이션이 적용된 메서드를 이용해서 익셉션을 처리하는 기능을 제공
하고 있다.
MVC 설정을 사용할 경우 다음의 순서대로 HandlerExceptionResolver를 사용하게 된다.
1. ExceptionHandlerExceptionResolver : 발생한 익셉션과 매칭되는 @Exception
Handler 메서드를 이용해서 익셉션을 처리한다.
2. DefaultHandlerExceptionResover : 스프링이 발생시키는 익셉션에 대한 처리.
예를들어,요청 URL에 매핑되는 컨트롤러가 없을 경우 NoHandlerFoundException이 발
생하는데,이 경우 DefaultHandlerExceptionResolver는 404 에러 코드를 응답으로
전송한다.
3. ResponseStatusExceptionResolver : 익셉션 타입에 @ResponseStatus 애노테이
션이 적용되어 있을 경우,@ResponseStatus 애노테이션의 값을 이용해서 응답 코드를
전송한다.
DispatcherServlet은 익셉션이 발생하면,가장 먼저 ExceptionHandlerExceptionResolver
에 익셉션 처리를 요청한다. 만약 익셉션에 매핑되는 @ExceptionHandler 메서드가 존재
하지 않으면, ExceptionHandlerExceptionResolver는 익셉션을 처리하지 않는다. 익셉션
이 처리되지 않으면 그 다음 차례인 DefaultHandlerExceptionResolver를 사용하고,여기서
도 익셉션을 처리하지않으면 마지막으로 ResponseStatusExceptionResolver사용한다.
마지막 차례인 ResponseStatusExceptionResolver에서도 익셉션을 처리하지 않으면,컨테
이너가 익셉션을 처리하도록 만든다.
2) @ControllerAdvice 애노테이션을 이용한 공통 익셉션 처리
컨트롤러 클래스에 @ExceptionHandler을 적용하면 해당 컨트롤러에서 발생한 익셉션만을 처리한
다. 그런데,다수의 컨트롤러에서 동일 타입의 익셉션을 발생시킬 수 있고, 이때 익셉션 처리 코드
가 동일하다면 어떻게 해야 할까? 각 컨트롤러 클래스마다 익셉션 처리 메서드를 구현하는 것은 불
필요한 코드 중복을 발생시킨다.
이렇게 여러 컨트롤러에서 동일한 익셉션을 발생시킬 경우,@ControllerAdvice 애노테
이션을 이용해서 익셉션 처리 메서드 중복을 없앨 수 있다.
@ControllerAdvice 애노테이션이 적용된 클래스는 지정한 범위의 컨트롤러에서 공통
으로 사용될 설정을 지정할 수 있다. 그러면 @ ControllerAdvice 클래스에 있는 @
ExceptionHandler 메서드를 통해서 익셉션을 처리하게 된다. 그리고
@ Controller Advice 적용 클래스가 동작하려면 해당 클래스를 스프링에 빈으로 등록해
주어야 한다.
@ Controller Advice 클래스에 있는 ExceptionHandler 메서드와 컨트롤러 클래스에
있는 ©ExceptionHandler 메서드 중 우선순위를 갖는 것은 컨트롤러 클래스에 적용된
©ExceptionHandler 클래스이다. 즉, 컨트롤러의 메서드를 실행하는 과정에서 익셉션
이 발생하면 다음의 순서로 익셉션을 처리할 ©ExceptionHandler 메서드를 찾는다.
© 같은 컨트롤러에 위치한 ©ExceptionHandler 메서드 중 해당 익셉션을 처리할 수 있는 메
서드를 검색
© 같은 클래스에 위치한 메서드가 익셉션을 처리할 수 없을 경우, @ControllerAdvice 클래
스에 위치한 @ExceptionHandler 메서드를 검색
3) @ResponseStatus을 이용한 익셉션 처리
@ResponseStatus 애노테이션은 익셉션 자체에 에러 응답 코드를 설정하고 싶을 때 사
용한다.
'BackEnd > Spring' 카테고리의 다른 글
스프링 mvc 프로젝트의 기본구성 (0) | 2020.02.10 |
---|---|
http 에러코드 (0) | 2020.02.10 |
컨트롤러의 리턴타입 (0) | 2020.02.09 |
Autowired 와 Resource 와 lnject 어노테이션정리 (0) | 2020.02.09 |
스프링 컨테이너 계층 구조 (0) | 2020.02.08 |