欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringMVC4.3?HandlerExceptionResolver異常處理源碼解析

 更新時(shí)間:2023年09月11日 14:06:51   作者:愛(ài)吃魚的KK  
這篇文章主要為大家介紹了SpringMVC4.3?HandlerExceptionResolver異常處理源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>

HandlerExceptionResolver 概述

HandlerExceptionResolver: 在處理 handler 映射 或執(zhí)行 HandlerExecutionChain/Handler 拋出的異常信息, 一般是返回對(duì)應(yīng)的 ModelAndView(PS: 設(shè)置 ViewName 與 Model 中的屬性信息), 其主接口如下:

// 針對(duì) 通過(guò) path 獲取 handler 或 執(zhí)行handler時(shí)出現(xiàn)異常的處理類
public interface HandlerExceptionResolver {
    // 通過(guò)解析異常查詢配置以得到符合條件的 ModelAndView 對(duì)象
    ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
}

其主要實(shí)現(xiàn)類如下:

1. SimpleMappingExceptionResolver
    在配置信息中配置 異常Class <-> ViewName的映射的 異常處理器
2. ResponseStatusExceptionResolver
    根據(jù)異常 class 上面的 @ResponseStatus 中注解的 Http Code 與 reson 進(jìn)行返回 ModeAndView
3. DefaultHandlerExceptionResolver
    默認(rèn)異常解析器, 進(jìn)行異常的類型進(jìn)行相應(yīng)的解析操作, 在 Http 頭部設(shè)置對(duì)應(yīng)的 Code, 最后返回對(duì)應(yīng)的 ModelAndView
4. ExceptionHandlerExceptionResolver
    通過(guò)激活在 方法上注釋 @ExceptionHandler 注解的方法來(lái)處理對(duì)應(yīng)的異常, 激活的操作通過(guò) InvocableHandlerMethod 來(lái)進(jìn)行操作 (Invocable 是 invoke的變形)
5. HandlerExceptionResolverComposite
    異常處理的組合模式類, 通過(guò)刷選滿足條件的 ExceptionResolver, 只要有能解決這個(gè)異常的, 則直接返回

簡(jiǎn)單異常處理類 SimpleMappingExceptionResolver

在這個(gè)類中主要有個(gè)存儲(chǔ)異常類型 class <-> ViewName 的 Properties, 存儲(chǔ) viewName <-> HttpCode的Properties, 當(dāng)出現(xiàn)異常了, 就通過(guò)這個(gè) properties 進(jìn)行獲取 viewName, 并通過(guò) viewName 獲取對(duì)應(yīng)的 HttpCode; 主要有如下屬性:

// 配置 異常 Class <--> ViewName 映射關(guān)系的 Property 的文件
private Properties exceptionMappings;
// 忽略的異常的類型
private Class<?>[] excludedExceptions;
// Set the name of the default error view 設(shè)置默認(rèn)的 錯(cuò)誤頁(yè)面
private String defaultErrorView;
// 默認(rèn)的 Http 返回的狀態(tài)值
private Integer defaultStatusCode;
// 這里配置的是 ViewName <--> Http Code 的映射關(guān)系
private Map<String, Integer> statusCodes = new HashMap<String, Integer>();

根據(jù) Exception 上的注解 ResponseStatus 設(shè)置httpCode 的ResponseStatusExceptionResolver

這個(gè)異常處理類比較簡(jiǎn)單, 主要是出了異常, 則根據(jù) Exception 上的注解@ResponseStatus 來(lái)獲取 HttpCode 與 ErrorMsg, 而返回的是一個(gè)空的 ModelAndView

默認(rèn)的異常處理類 DefaultHandlerExceptionResolver

這是一個(gè)根據(jù)異常的類型設(shè)置 http code 與 ErrorMsg 的 異常處理類, 主要處理的異常如下:

1. 處理 NoSuchRequestHandlingMethodException, 設(shè)置 http code 404 --> SC_NOT_FOUND
2. 處理 HttpRequestMethodNotSupportedException, 設(shè)置 http code 405 -- > SC_METHOD_NOT_ALLOWED
3. 處理 HttpMediaTypeNotSupportedException, 設(shè)置 http code 415 --> SC_UNSUPPORTED_MEDIA_TYPE
4. 處理 HttpMediaTypeNotAcceptableException, 設(shè)置 http code 406 --> SC_NOT_ACCEPTABLE
5. 處理 MissingPathVariableException, 設(shè)置 http code 500 --> SC_INTERNAL_SERVER_ERROR
6. 處理 MissingServletRequestParameterException, 設(shè)置 http code 400 --> SC_BAD_REQUEST
7. 處理 ServletRequestBindingException, 設(shè)置 http code 400 --> SC_BAD_REQUEST
8. 處理 ConversionNotSupportedException, 設(shè)置 http code 500 --> SC_INTERNAL_SERVER_ERROR
9. 處理 TypeMismatchException, 設(shè)置 http code 400 --> SC_BAD_REQUEST
10. 處理 HttpMessageNotReadableException, 設(shè)置 http code 400 --> SC_BAD_REQUEST
11. 處理 HttpMessageNotWritableException, 設(shè)置 http code 500 --> SC_INTERNAL_SERVER_ERROR
12. 處理 MethodArgumentNotValidException, 設(shè)置 http code 400 --> SC_BAD_REQUEST
13. 處理 MissingServletRequestPartException, 設(shè)置 http code 400 --> SC_BAD_REQUEST
14. 處理 BindException, 設(shè)置 http code 400 --> SC_BAD_REQUEST
15. 處理 NoHandlerFoundException, 設(shè)置 http code 404 --> SC_NOT_FOUND
16. 處理 AsyncRequestTimeoutException, 設(shè)置 http code 503 --> SC_SERVICE_UNAVAILABLE

基于注解@ExceptionHandler 的異常處理類 ExceptionHandlerExceptionResolver

其實(shí)就是在指定的方法上標(biāo)注 @ExceptionHandler 最后通過(guò) InvocableHandlerMethod 進(jìn)行激活方法 <-- 這個(gè)方法就是處理異常的; 其主要有如下屬性:

// HandlerMethod 參數(shù)解析器
private List<HandlerMethodArgumentResolver> customArgumentResolvers;
// 組合模式的 HandlerMethod 參數(shù)解析器
private HandlerMethodArgumentResolverComposite argumentResolvers;
// HandlerMethod 返回值處理器
private List<HandlerMethodReturnValueHandler> customReturnValueHandlers;
// 組合模式的 HandlerMethod 返回值處理器
private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
// Http 消息轉(zhuǎn)換器
private List<HttpMessageConverter<?>> messageConverters;
// MediaType 解決器(PS: 根據(jù)請(qǐng)求 uri 尾綴, 或 Header 中的信息, 來(lái)決定 MediaType)
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
// 對(duì) Response 進(jìn)行增強(qiáng)的 Advice
private final List<Object> responseBodyAdvice = new ArrayList<Object>();
// IOC 工廠類
private ApplicationContext applicationContext;
// 緩存異常處理類 key: 包含處理異常的方法, value: ExceptionHandlerMethodResolver <-- 這里包含了 Exception <--> method 的鍵值對(duì)
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache = new ConcurrentHashMap<Class<?>, ExceptionHandlerMethodResolver>(64);
// 被 @ControllerAdvice 注解修飾的的處理類, 再被包裝成 ExceptionHandlerMethodResolver
private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache = new LinkedHashMap<ControllerAdviceBean, ExceptionHandlerMethodResolver>();

而對(duì)應(yīng)的激活方法主要如下:

// 這里是獲取 能處理異常 Exception 的handler, 并且封裝成 ServletInvocableHandlerMethod
// (PS: InvocableHandlerMethod 主要是激活方法, 并且通過(guò) HandlerMethodReturnValueHandler 來(lái)處理一下返回值, 這里的參數(shù) providedArgs 是首選參數(shù), 比如說(shuō)異常處理的 InvocableHandlerMethod, 這時(shí)會(huì)傳來(lái)參數(shù) Exception, cause)
ServletInvocableHandlerMethod exceptionHandlerMethod = getExceptionHandlerMethod(handlerMethod, exception);
if (exceptionHandlerMethod == null) return null;
// 給 ServletInvocableHandlerMethod 設(shè)置 argumentResolver
exceptionHandlerMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
// 給 ServletInvocableHandlerMethod 設(shè)置 returnValueHandler
exceptionHandlerMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);  
// 封裝統(tǒng)一的 Request 類
ServletWebRequest webRequest = new ServletWebRequest(request, response);
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
try {
    logger.debug("Invoking @ExceptionHandler method: " + exceptionHandlerMethod);
    Throwable cause = exception.getCause();
    if (cause != null) { // Expose cause as provided argument as well // 激活處理異常的方法 (首選參數(shù)是 exception, cause)
        exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception, cause, handlerMethod);
    } else { // 若 cause == null, 則只傳遞 exception
        exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception, handlerMethod);
    }
}catch (Throwable invocationEx) {
    return null;
}

總結(jié)

總體上 HandlerExceptionResolver 的設(shè)計(jì)體系和HandlerMethodArgumentResolver 差不多, 設(shè)計(jì)上夾雜著策略, 模版, 適配器 等等, 而我們常用的 @ ExceptionHandler 就是通過(guò)ExceptionHandlerExceptionResolver 來(lái)解決的(PS: 將異常信息及Cause 作為參數(shù)傳入 InvocableHandlerMethod, 最終激活方法)!

以上就是SpringMVC4.3 HandlerExceptionResolver源碼解析的詳細(xì)內(nèi)容,更多關(guān)于SpringMVC HandlerExceptionResolver異常處理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java微信公眾號(hào)支付開(kāi)發(fā)之現(xiàn)金紅包

    java微信公眾號(hào)支付開(kāi)發(fā)之現(xiàn)金紅包

    這篇文章主要為大家詳細(xì)介紹了java微信公眾號(hào)支付開(kāi)發(fā)之現(xiàn)金紅包,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • C# TreeNode案例詳解

    C# TreeNode案例詳解

    這篇文章主要介紹了C# TreeNode案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • java采用中文方式顯示時(shí)間的方法

    java采用中文方式顯示時(shí)間的方法

    這篇文章主要介紹了java采用中文方式顯示時(shí)間的方法,實(shí)例分析了java時(shí)間操作及字符串轉(zhuǎn)換的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • Mybatis-Plus通用枚舉的使用詳解

    Mybatis-Plus通用枚舉的使用詳解

    這篇文章主要介紹了Mybatis-Plus通用枚舉的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 如何利用JAVA正則表達(dá)式輕松替換JSON中的大字段

    如何利用JAVA正則表達(dá)式輕松替換JSON中的大字段

    這篇文章主要給大家介紹了關(guān)于如何利用JAVA正則表達(dá)式輕松替換JSON中大字段的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 攔截Druid數(shù)據(jù)源自動(dòng)注入帳密解密實(shí)現(xiàn)詳解

    攔截Druid數(shù)據(jù)源自動(dòng)注入帳密解密實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了攔截Druid數(shù)據(jù)源自動(dòng)注入帳密解密實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • SpringBoot常用注解詳細(xì)整理

    SpringBoot常用注解詳細(xì)整理

    大家好,本篇文章主要講的是SpringBoot常用注解詳細(xì)整理,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Java面向?qū)ο笾^承性的實(shí)例代碼詳解

    Java面向?qū)ο笾^承性的實(shí)例代碼詳解

    這篇文章主要介紹了Java面向?qū)ο笾^承性,文中代碼簡(jiǎn)單易懂,可以更好的幫助大家學(xué)習(xí),有興趣的小伙伴快來(lái)了解下
    2020-05-05
  • java線程池使用場(chǎng)景及一些建議

    java線程池使用場(chǎng)景及一些建議

    本文主要介紹了java線程池使用場(chǎng)景及一些建議,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Springboot中加入druid連接池

    Springboot中加入druid連接池

    這篇文章主要介紹了Springboot中加入druid連接池,Druid是目前最好的數(shù)據(jù)庫(kù)連接池。在功能、性能、擴(kuò)展性方面,都超過(guò)其他數(shù)據(jù)庫(kù)連接池,同時(shí)加入了日志監(jiān)控,下面來(lái)看看文章的具體內(nèi)容吧
    2022-01-01

最新評(píng)論