반응형



컨트롤러나 그 뒤의 계층에서 던져진 예외는 DispatcherServlet 이 일단 전달받은 뒤에 다시 서블릿 밖으로 뎐져서 서블릿 컨테이너가 처리

다른 설정을 하지 않았다면 브라우저에 'HTTP Status 500 내부 서버 오류' 와 같은 메시지가 출력

web.xml 에 <error-page> 를 저정해서 예외가 발생했을 때 JSP 안내 페이지 등을 보여줄 수도 있다

만약 스프링과 서블릿 컨테이너에서 같이 java.lang.Exception 을 처리한다면 스프링 처리가 더 우선시 된다.


HandlerExceptionResolver 는 컨트롤러의 작업 중에 발생한 예외를 어떻게 처리할지 결정하는 전략

DispatcherServlet 은 먼저 핸들러 예외 리졸버에게 해당 예외를 처리할 수 있는지 확인

예외를 처리해주는 핸들러 예외 리졸버가 있으면 예외는 DispatcherServlet 밖으로 던지지 않고 해당 핸들러 예외 리졸버가 처리

핸들러 예외 리졸버는 HandlerExceptionResovler 인터페이스를 구현

 - resolveException() 메소드의 리턴 타입은 ModelAndView

 - 사용할 뷰와  그 안에 들어갈 내용을 담은 모델을 돌려주도록 되어 있다.만약 처리 불가능한 예외라면 null 을 리턴

 

스프링은 총 4개의 HandlerExceptionResolver 구현 전략을 제공하고 있다. 그중 3개는 디폴트로 등록

AnnotationMethodHandlerExceptionResolver

 - 디폴트 핸들러 예외 리졸버

 - 예외가 발생한 컨트롤러 내의 메소드 중에서 @ExceptionHandler 애노테이션이 붙은 메소드를 찾아 예외처리

 - 특정 컨트롤러의 작업 중에 발생하는 예외만 처리하는 예외 핸들러를 만들고 싶다면 이 방법이 가장 편리하다.

 - @ResponseBody 사용시 convert 정의 : AnnotationMethodHandlerExceptionResolver

 - 예외처리용 메소드는 모델과 뷰를 리턴할 수 있는데, 모델과 뷰가 정상적으로 리턴되면 DispatcherServlet 은 마치 컨트롤러에서 ModelAndView 가 돌려진 것처럼 뷰를 통해 결과를 만들어 준다

 

ResponseStatusExceptionResolver

 - 특정 예외가 발생했을 때 단순한 HTTP 500 에러 대신 의미 있는 HTTP 응답 상태를 돌려주는 방법

 - 예외 클래스에 @ResponseStatus 를 붙이고, HttpStatus 에 정의되어 있는 HTTP 응답 상태 값을 value 엘리먼트에 지정한다. 필요하면 reason 에 자세한 설명을 넣을 수도 있다.

 - ex ) 애노테이션을 이용해 HTTP 503 응답 상태를 지정해둔 예외클래스

@ResponseStatus(value=HttpStatus.SERVICE_UNAVAILABLE, reason="서비스 일시 중지"

public class NotInServiceException extends RuntimeException {

}

 - 발생한 예외 클래스에 @ResponseStatus 가 있는지 확인하고, 만약 있다면 애노테이션에 지정해둔 HTTP 응답 상태 코드를 클라이언트에 전달.

 - HttPStatus 클래스 안에는 40여 개의 사용 가능한 HTTP 응답 상태 상수가 정의

 - 단점은 적접 @ResponseStatus 를 붙여줄 수 있는 예외 클래스를 만들어 사용해야 한다는 것이다. 따라서 기존에 정의된 예외 클래스에는 바로 적용할 수 없다.

 - @ResponseStatus 를 직접 부여할 수 없는 기존의 예외가 발생했을 때 HTTP 응답 상태를 지정해 주려면 @ExceptionHandler 방식의 핸들러 메소드를 사용하면 된다. 

   기존의 예외를 처리하는 @ExceptionHandler 메소드를 만들고 리턴 타입은 void 로 해둔다. 

   그리고 HttpServletResponse 를 파라미터로 전달 받아서 setStatus() 메소드를 이용해 응답 상태와 에러 메시지 등을 설정

   

   

DefaultHandlerExceptionResolver

 - 디폴트로 등록된 것 중에서 위의 두 가지 예외 리졸버에서 처리하지 못한 예외를 다루는 마지막 핸들러 예외 리졸버

 - 스프링에서 내부적으로 발생하는 주요 예외를 처리해주는 표준 예외처리 로직을 담고 있다.

 - 예를 들어 컨트롤러 메소드를 찾을 수 없는 경우에는 NoSuchRequestHandlingMethodException 예외가 발생한다. 

   이 예외에 대해서는 HTTP 404 - Not Found 로 응답 상태를 지정해준다. 

   또, 요청 파라미터를 파싱하다가 타입이 일치하지 않을 때 발생하는 TypeMismatchException 은 HTTP 400 - Bad Request 응답 상태로 돌려주는 식이다.

 -  다른 핸들러 예외 리졸버를 빈으로 등록해서 디폴트 예외 리졸버가 자동으로 적용되지 않은 경우에는 DefaultHandlerExceptionResolver 를 함께 등록해 주는게 좋다.


SimpleMappingExceptionResolver

 - SimpleMappingExceptionResolver 는 web.xml 의 <error-page> 와 비슷하게 예외를 처리할 뷰를 지정할 수 있게 해준다.

 - mappedHandlers 에서는 예외와 그에 대응하는 뷰 이름을 프로퍼티로 등록해주면 된다.

 - defaultErrorView 프로퍼티는 mappedHandlers 에서 찾을 수 없는 예외에 매핑해주는 디폴트 예외처리 뷰 이름.

 - SimpleMappingExceptionResolver 는 디폴트 전략이 아니므로 직접 빈으로 등록해줘야 한다. xml 또는 @Bean 으로.

 - 모든 컨트롤러에서 발생하는 예외에 일괄적용된다는 장점

 - 예외가 발생했을 때 로그를 남기거나 관리자에게 통보하는 등의 작업을 필요로 하는 경우도 있다. 이런 작업은 핸들러 인터셉터의 afterCompletion() 메소드가 담당하는 것이 좋다.



반응형

'프로그래밍 > Java' 카테고리의 다른 글

이클립스 단축키  (0) 2014.03.24
[이클립스] tptp  (1) 2014.03.24
[java 7] copy file, delete file/directory  (0) 2014.03.21
[MyBatis] null parameter 에러.  (0) 2014.03.19
[iBatis/myBatis] #와 $의 차이점  (1) 2014.01.02

+ Recent posts