首頁  >  文章  >  Java  >  SpringBoot異常處理的原理分析

SpringBoot異常處理的原理分析

WBOY
WBOY轉載
2023-05-13 23:28:131257瀏覽

異常處理流程

執行目標方法,目標方法運行期間有任何異常都會被catch捕獲,並標誌當前請求結束,dispatchException拋出異常

SpringBoot異常處理的原理分析

進入視圖解析流程,並渲染頁面,發生例外狀況時,參數mv為空,傳入擷取的例外dispatchException

SpringBoot異常處理的原理分析

處理handler發生的異常,處理完成返回ModelAndView

SpringBoot異常處理的原理分析

(1)遍歷所有的HandlerExceptionResolvers#,找到可以處理目前例外的解析器來解析異常

SpringBoot異常處理的原理分析

(2)呼叫 resolveException解析異常,傳入requestresponse對象,哪個方法,發生的異常,然後自訂異常處理返回ModelAndView

SpringBoot異常處理的原理分析

#(3)系統預設的例外解析器

SpringBoot異常處理的原理分析

#① DefaultErrorAttributes先來處理異常,把異常資訊保存到request網域並傳回null

SpringBoot異常處理的原理分析

② ExceptionHandlerExceptionResolver用來處理標註了@ExceptionHandler註解的方法異常

③ ResponseStatusExceptionResolver用來處理標註了@ResponseStatus註解的方法例外

 ##④

SpringBoot異常處理的原理分析

#CC😢 #DefaultHandlerExceptionResolver預設的處理器異常解析器,處理一些常見的異常(4)如果沒有任何解析器能夠處理異常,異常就會拋出#(5)如果沒有任何解析器能夠處理當前異常,最終就會發送/error請求,將已儲存的異常訊息轉送到/errorBasicErrorController專門來處理

/error

要求,

BasicErrorController

會遍歷所有的ErrorViewResolver解析錯誤視圖,如果沒有自訂的錯誤視圖解析器,就會使用預設的DefaultErrorViewResolver,會把回應碼當作錯誤頁的位址,模板引擎最終會回應這個頁面。 幾種異常處理方式及原理

1.自訂錯誤頁,error/404.htmlerror/5xx.html。有精確的錯誤狀態碼頁面就匹配精確,沒有就找 4xx.html,如果都沒有就觸發白頁

2.使用SpringBoot異常處理的原理分析@ControllerAdvice

@ExceptionHandler處理全域異常,底層是ExceptionHandlerExceptionResolver 支援的3.使用@ResponseStatus和自定義異常。底層是 ResponseStatusExceptionResolver ,底層呼叫 response.sendError(statusCode, resolvedReason),Tomcat會收到一個error#。請求最後new一個空的ModelAndView返回,這樣任何處理解析器都處理不了當前的異常,最終就會發送/error請求,

BasicErrorController

專門處理SpringBoot異常處理的原理分析/error
請求,適配

4xx.html

5xx.html頁面##4.Spring底層的異常,如參數類型轉換異常。底層是DefaultHandlerExceptionResolver 處理框架底層的例外,底層也是

response.sendError(HttpServletResponse.SC_NOT_ACCEPTABLE)###,Tomcat會收到一個###error.SC_NOT_ACCEPTABLE)###,Tomcat會收到一個###error#。請求最後###new###一個空的###ModelAndView###返回,這樣任何處理解析器都處理不了當前的異常,最終就會發送###/error###請求,### BasicErrorController###專門處理###/error###請求,適合###4xx.html###或###5xx.html###頁面###
protected ModelAndView doResolveException(
			HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {

		try {
			if (ex instanceof HttpRequestMethodNotSupportedException) {
				return handleHttpRequestMethodNotSupported(
						(HttpRequestMethodNotSupportedException) ex, request, response, handler);
			}
			else if (ex instanceof HttpMediaTypeNotSupportedException) {
				return handleHttpMediaTypeNotSupported(
						(HttpMediaTypeNotSupportedException) ex, request, response, handler);
			}
			else if (ex instanceof HttpMediaTypeNotAcceptableException) {
				return handleHttpMediaTypeNotAcceptable(
						(HttpMediaTypeNotAcceptableException) ex, request, response, handler);
			}
			else if (ex instanceof MissingPathVariableException) {
				return handleMissingPathVariable(
						(MissingPathVariableException) ex, request, response, handler);
			}
			else if (ex instanceof MissingServletRequestParameterException) {
				return handleMissingServletRequestParameter(
						(MissingServletRequestParameterException) ex, request, response, handler);
			}
			else if (ex instanceof ServletRequestBindingException) {
				return handleServletRequestBindingException(
						(ServletRequestBindingException) ex, request, response, handler);
			}
			else if (ex instanceof ConversionNotSupportedException) {
				return handleConversionNotSupported(
						(ConversionNotSupportedException) ex, request, response, handler);
			}
			else if (ex instanceof TypeMismatchException) {
				return handleTypeMismatch(
						(TypeMismatchException) ex, request, response, handler);
			}
			else if (ex instanceof HttpMessageNotReadableException) {
				return handleHttpMessageNotReadable(
						(HttpMessageNotReadableException) ex, request, response, handler);
			}
			else if (ex instanceof HttpMessageNotWritableException) {
				return handleHttpMessageNotWritable(
						(HttpMessageNotWritableException) ex, request, response, handler);
			}
			else if (ex instanceof MethodArgumentNotValidException) {
				return handleMethodArgumentNotValidException(
						(MethodArgumentNotValidException) ex, request, response, handler);
			}
			else if (ex instanceof MissingServletRequestPartException) {
				return handleMissingServletRequestPartException(
						(MissingServletRequestPartException) ex, request, response, handler);
			}
			else if (ex instanceof BindException) {
				return handleBindException((BindException) ex, request, response, handler);
			}
			else if (ex instanceof NoHandlerFoundException) {
				return handleNoHandlerFoundException(
						(NoHandlerFoundException) ex, request, response, handler);
			}
			else if (ex instanceof AsyncRequestTimeoutException) {
				return handleAsyncRequestTimeoutException(
						(AsyncRequestTimeoutException) ex, request, response, handler);
			}
		}
		catch (Exception handlerEx) {
			if (logger.isWarnEnabled()) {
				logger.warn("Failure while trying to resolve exception [" + ex.getClass().getName() + "]", handlerEx);
			}
		}
		return null;
	}

5.自訂實作 HandlerExceptionResolver 處理異常,可以作為預設的全域例外處理規則

@Order(value = Ordered.HIGHEST_PRECEDENCE)
@Component
public class CustomerHandlerExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

        try {
            response.sendError(521,"I love you !");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ModelAndView();
    }
}

SpringBoot異常處理的原理分析

ErrorViewResolver實作自訂處理異常。

(1)底層呼叫response.sendError時,error要求就會預設轉給basicErrorControllerBasicErrorController專門處理/error請求,適配器4xx.html5xx.html頁面

(2)如果異常沒有任何解析器能處理,tomcat底層也會呼叫response.sendErrorerror請求就會預設轉給basicErrorControllerBasicErrorController專門處理/error請求,適配4xx.html5xx.html頁。

(3)basicErrorController 要去的頁面位址是由 ErrorViewResolver這個錯誤視圖解析器決定的,也就是適應4xx.html5xx.html頁。

以上是SpringBoot異常處理的原理分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除