@Controller
및 @ControllerAdvice 클래스는 다음 예제와 같이 컨트롤러 메서드의 예외를 처리하기 위해 @ExceptionHandler
메서드를 가질 수 있습니다.
@Controller
public class SimpleController {
// ...
@ExceptionHandler
public ResponseEntity<String> handle(IOException ex) {
// ...
}
}
예외는 전파되는 최상위 예외(예: 직접 IOException
발생) 또는 래퍼 예외 내의 중첩 원인(예: IllegalStateException
내에 래핑된 IOException
)과 일치할 수 있습니다. 5.3부터는 임의의 원인 수준에서 일치할 수 있지만 이전에는 즉각적인 원인만 고려되었습니다.
일치하는 예외 유형의 경우 앞의 예제와 같이 대상 예외를 메서드 인수로 선언하는 것이 좋습니다. 여러 예외 메서드가 일치하는 경우 일반적으로 원인 예외 일치보다 루트 예외 일치가 선호됩니다. 보다 구체적으로 ExceptionDepthComparator
는 발생한 예외 유형의 깊이를 기준으로 예외를 정렬하는 데 사용됩니다.
또는 다음 예제와 같이 annotation 선언을 통해 일치하도록 예외 유형을 좁힐 수 있습니다.
@ExceptionHandler({FileSystemException.class, RemoteException.class})
public ResponseEntity<String> handle(IOException ex) {
// ...
}
다음 예제와 같이 매우 일반적인 인수 서명과 함께 특정 예외 유형 목록을 사용할 수도 있습니다.
@ExceptionHandler({FileSystemException.class, RemoteException.class})
public ResponseEntity<String> handle(Exception ex) {
// ...
}
[Note]
근본 예외 일치와 원인 예외 일치 사이의 차이는 놀라울 수 있습니다.앞서 표시된
IOException
변형에서 메서드는 일반적으로 실제FileSystemException
또는RemoteException
인스턴스를 인수로 사용하여 호출됩니다. 둘 다IOException
에서 확장되기 때문입니다. 그러나 일치하는 예외가 그 자체가IOException
인 래퍼 예외 내에서 전파되는 경우 전달된 예외 인스턴스는 해당 래퍼 예외입니다.
handle(Exception)
변형에서는 동작이 훨씬 더 간단합니다. 이는 항상 래핑 시나리오에서 래퍼 예외와 함께 호출되며, 이 경우 실제로 일치하는 예외는ex.getCause()
를 통해 찾을 수 있습니다. 전달된 예외는 최상위 예외로 발생하는 경우에만 실제FileSystemException
또는RemoteException
인스턴스입니다.
일반적으로 인수 서명을 최대한 구체적으로 지정하여 루트 예외 유형과 원인 예외 유형 간의 불일치 가능성을 줄이는 것이 좋습니다. 다중 일치 메서드를 개별 @ExceptionHandler
메서드로 분리하는 것을 고려하세요. 각 메서드는 서명을 통해 단일 특정 예외 유형과 일치합니다.
다중 @ControllerAdvice
배열에서는 해당 순서에 따라 우선순위가 지정된 @ControllerAdvice
에 기본 루트 예외 매핑을 선언하는 것이 좋습니다. 원인보다 루트 예외 일치가 선호되는 반면 이는 지정된 컨트롤러 또는 @ControllerAdvice
클래스의 메서드 간에 정의됩니다. 이는 우선순위가 높은 @ControllerAdvice
빈의 원인 일치가 우선순위가 낮은 @ControllerAdvice
빈의 모든 일치(예: 루트)보다 선호됨을 의미합니다.
마지막으로 @ExceptionHandler
메소드 구현은 주어진 예외 인스턴스를 원래 형식으로 다시 발생시켜 처리를 취소하도록 선택할 수 있습니다. 이는 루트 수준 일치에만 관심이 있거나 정적으로 확인할 수 없는 특정 컨텍스트 내의 일치에만 관심이 있는 시나리오에서 유용합니다. 다시 던져진 예외는 주어진 @ExceptionHandler
메소드가 처음부터 일치하지 않은 것처럼 나머지 해결 체인을 통해 전파됩니다.
Spring MVC의 @ExceptionHandler
메소드에 대한 지원은 DispatcherServlet
레벨, HandlerExceptionResolver 메커니즘을 기반으로 구축되었습니다.
@ExceptionHandler
메소드는 다음 인수를 지원합니다:
매개변수 | 설명 |
---|---|
예외 유형 |
발생한 예외에 대한 접근 |
|
예외를 발생시킨 컨트롤러 메서드에 대한 접근 |
|
Servlet API를 직접 사용하지 않고 요청 매개변수 및 요청 및 세션 속성에 대한 일반적인 접근 |
|
특정 요청 또는 응답 유형 선택(예: |
|
세션의 존재를 강제합니다. 따라서 이러한 매개변수는 절대 |
|
현재 인증된 사용자 - 알려진 특정 |
|
요청의 HTTP 메서드 |
|
가장 구체적인 사용 가능한 |
|
현재 요청과 관련된 시간대, |
|
Servlet API에 의해 노출된 원시 응답 본문에 대한 액세스 |
|
오류 응답의 모델에 액세스하기 위해 사용됩니다. 항상 비어 있습니다. |
|
리다이렉트 경우 사용할 속성 지정 - (쿼리 문자열에 추가될) 및 리다이렉트 후 요청 전까지 일시적으로 저장될 플래시 속성. Redirect Attributes 및 Flash Attributes 참조 |
|
클래스 수준의 |
|
요청 속성에 액세스합니다. 자세한 내용은 |
@ExceptionHandler
메서드는 다음 반환 값을 지원합니다.
리턴 값 | 설명 |
---|---|
|
리턴 값은 |
|
리턴 값은 전체 응답(포함하여 HTTP 헤더 및 본문)이 |
|
바디에 세부 정보를 포함한 RFC 7807 오류 응답을 렌더링합니다. 자세한 내용은 오류 응답을 참조하십시오. |
|
바디에 세부 정보를 포함한 RFC 7807 오류 응답을 렌더링합니다. 자세한 내용은 오류 응답을 참조하십시오. |
|
|
|
암시적 모델과 함께 렌더링에 사용할 |
|
암시적 모델에 추가할 속성으로, 뷰 이름은 |
|
암시적으로 |
|
사용할 뷰 및 모델 속성 및 선택적으로 응답 상태입니다. |
|
는 위의 조건이 모두 참이 아니면 |
다른 반환 값 |
반환 값이 위의 어느 것과 일치하지 않고 단순한 유형이 아닌 경우(BeanUtils#isSimpleProperty에 의해 결정됨), 기본적으로 모델 속성으로 처리됩니다. 단순한 유형인 경우 해결되지 않습니다. |