Exceptions

Dev.Hammy·2024년 4월 6일
0

반응형 스택에서 이에 상응하는 내용 보기

@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 메커니즘을 기반으로 구축되었습니다.

Method Arguments

반응형 스택에서 이에 상응하는 내용 보기

@ExceptionHandler 메소드는 다음 인수를 지원합니다:

매개변수 설명

예외 유형

발생한 예외에 대한 접근

HandlerMethod

예외를 발생시킨 컨트롤러 메서드에 대한 접근

WebRequest, NativeWebRequest

Servlet API를 직접 사용하지 않고 요청 매개변수 및 요청 및 세션 속성에 대한 일반적인 접근

jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse

특정 요청 또는 응답 유형 선택(예: ServletRequest 또는 HttpServletRequest 또는 Spring의 MultipartRequest 또는 MultipartHttpServletRequest)

jakarta.servlet.http.HttpSession

세션의 존재를 강제합니다. 따라서 이러한 매개변수는 절대 null이 아닙니다.
세션 액세스는 스레드 안전하지 않습니다. 여러 요청이 동시에 세션에 액세스할 수 있는 경우 RequestMappingHandlerAdapter 인스턴스의 synchronizeOnSession 플래그를 true로 설정하는 것이 좋습니다.

java.security.Principal

현재 인증된 사용자 - 알려진 특정 Principal 구현 클래스일 수 있습니다.

HttpMethod

요청의 HTTP 메서드

java.util.Locale

가장 구체적인 사용 가능한 LocaleResolver에 의해 결정된 현재 요청 로케일 - 즉, 구성된 LocaleResolver 또는 LocaleContextResolver의 효과.

java.util.TimeZone, java.time.ZoneId

현재 요청과 관련된 시간대, LocaleContextResolver에 의해 결정됩니다.

java.io.OutputStream, java.io.Writer

Servlet API에 의해 노출된 원시 응답 본문에 대한 액세스

java.util.Map, org.springframework.ui.Model, org.springframework.ui.ModelMap

오류 응답의 모델에 액세스하기 위해 사용됩니다. 항상 비어 있습니다.

RedirectAttributes

리다이렉트 경우 사용할 속성 지정 - (쿼리 문자열에 추가될) 및 리다이렉트 후 요청 전까지 일시적으로 저장될 플래시 속성. Redirect AttributesFlash Attributes 참조

@SessionAttribute

클래스 수준의 @SessionAttributes 선언 결과로 세션에 저장된 모델 속성과 달리 모든 세션 속성에 액세스합니다. 자세한 내용은 @SessionAttribute를 참조하세요.

@RequestAttribute

요청 속성에 액세스합니다. 자세한 내용은 @RequestAttribute를 참조하세요.

Return Values

반응형 스택에서 이에 상응하는 내용 보기

@ExceptionHandler 메서드는 다음 반환 값을 지원합니다.

리턴 값 설명

@ResponseBody

리턴 값은 HttpMessageConverter 인스턴스를 통해 변환되어 응답으로 작성됩니다. 자세한 내용은 @ResponseBody를 참조하십시오.

HttpEntity<B>, ResponseEntity<B>

리턴 값은 전체 응답(포함하여 HTTP 헤더 및 본문)이 HttpMessageConverter 인스턴스를 통해 변환되어 응답으로 작성되도록 지정됩니다. 자세한 내용은 ResponseEntity를 참조하십시오.

ErrorResponse

바디에 세부 정보를 포함한 RFC 7807 오류 응답을 렌더링합니다. 자세한 내용은 오류 응답을 참조하십시오.

ProblemDetail

바디에 세부 정보를 포함한 RFC 7807 오류 응답을 렌더링합니다. 자세한 내용은 오류 응답을 참조하십시오.

String

ViewResolver 구현체를 사용하여 해결될 뷰 이름과 함께 암시적 모델과 함께 사용될 뷰 이름입니다 — 명령 객체 및 @ModelAttribute 메소드를 통해 결정됩니다. 핸들러 메소드는 Model 인자를 선언하여 모델을 프로그래밍 방식으로 보강할 수도 있습니다(이전에 설명된대로).

View

암시적 모델과 함께 렌더링에 사용할 View 인스턴스입니다 — 명령 객체 및 @ModelAttribute 메소드를 통해 결정됩니다. 핸들러 메소드는 Model 인자를 선언하여 모델을 프로그래밍 방식으로 보강할 수도 있습니다(이전에 설명된대로).

java.util.Map, org.springframework.ui.Model

암시적 모델에 추가할 속성으로, 뷰 이름은 RequestToViewNameTranslator를 통해 암시적으로 결정됩니다.

@ModelAttribute

암시적으로 RequestToViewNameTranslator를 통해 결정된 뷰 이름과 함께 모델에 추가할 속성입니다.

@ModelAttribute은 선택 사항입니다. 이 테이블의 끝 부분의 “다른 반환 값”을 참조하십시오.

ModelAndView 객체

사용할 뷰 및 모델 속성 및 선택적으로 응답 상태입니다.

void

void 반환 유형(또는 null 반환 값)을 갖는 메소드는 ServletResponse 또는 OutputStream 인자 또

@ResponseStatus 어노테이션이 있으면 완전히 응답을 처리한 것으로 간주됩니다. 컨트롤러가 긍정적인 ETag 또는 lastModified 타임스탬프 확인을 수행했으면 동일합니다(세부 사항은 컨트롤러를 참조하십시오).

위의 조건이 모두 참이 아니면 void 반환 유형은 REST 컨트롤러의 경우 “응답 본문 없음” 또는 HTML 컨트롤러의 경우 기본 뷰 이름 선택을 나타낼 수도 있습니다.

다른 반환 값

반환 값이 위의 어느 것과 일치하지 않고 단순한 유형이 아닌 경우(BeanUtils#isSimpleProperty에 의해 결정됨), 기본적으로 모델 속성으로 처리됩니다. 단순한 유형인 경우 해결되지 않습니다.

0개의 댓글