精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

SpringMVC的異常處理機制詳細分析

開發(fā) 架構(gòu)
DispatcherServlet和任何Servlet一樣,需要使用Java配置或web.xml根據(jù)Servlet規(guī)范進行聲明和映射。然后,DispatcherServlet使用Spring配置來發(fā)現(xiàn)它在請求映射、視圖解析、異常處理等方面所需的委托組件。

環(huán)境:Springboot2.4.12

請求入口

SpringMVC的請求處理入口是DispatcherServlet,不過該Servlet不做實際的處理而實際的處理是由可其它配置的委托組件執(zhí)行的。

DispatcherServlet和任何Servlet一樣,需要使用Java配置或web.xml根據(jù)Servlet規(guī)范進行聲明和映射。然后,DispatcherServlet使用Spring配置來發(fā)現(xiàn)它在請求映射、視圖解析、異常處理等方面所需的委托組件。如下配置示例:

public class CustomWebApplicationInitializer implements WebApplicationInitializer {

@Override
public void onStartup(ServletContext servletContext) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(WebConfig.class);
DispatcherServlet servlet = new DispatcherServlet(context);
ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);
registration.setLoadOnStartup(1);
registration.addMapping("/app/*");
}
}

這里為何需要實現(xiàn)WebApplicationInitializer 這需要你先了解Servlet3.0+的新特性ServletContainerInitializer

下面方法是DispatcherServlet處理的核心方法:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
Exception dispatchException = null;
// 1.獲取HandlerMapping(該對象就是當前請求與處理程序的一個映射關(guān)系)
mappedHandler = getHandler(processedRequest);
// 2.獲取能夠處理上一步得到的處理程序
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3.執(zhí)行實際的調(diào)用(執(zhí)行實際的處理程序)
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
} catch (Exception ex) {
// 4.執(zhí)行過程中發(fā)生異常記錄到局部變量中
dispatchException = ex;
} catch (Throwable err) {
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
// 5.處理結(jié)果
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}

上面只是把核心的代碼貼出。

處理結(jié)果

接著上一步中繼續(xù)執(zhí)行,這里就會根據(jù)上一步執(zhí)行過程中是否發(fā)生異常(異常對象是否為空)。

private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
@Nullable Exception exception) throws Exception {

boolean errorView = false;
// 1.判斷是否發(fā)生異常
if (exception != null) {
// 1.1.異常對象是否是該對象
if (exception instanceof ModelAndViewDefiningException) {
mv = ((ModelAndViewDefiningException) exception).getModelAndView();
} else {
// 如果不是上面的異常對象,則這里獲取具體處理程序的Handler
// 這里我們只考慮RequestMappingHandlerMapping情況,那么這里獲取的將是HandlerMethod對象
// 也就是Controller中的具體方法了
Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
// 處理異常,查看下面processhandlerException方法
mv = processHandlerException(request, response, handler, exception);
errorView = (mv != null);
}
}

// Did the handler return a view to render?
if (mv != null && !mv.wasCleared()) {
render(mv, request, response);
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("No view rendering, null ModelAndView returned.");
}
}

if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
// Concurrent handling started during a forward
return;
}

if (mappedHandler != null) {
// Exception (if any) is already handled..
mappedHandler.triggerAfterCompletion(request, response, null);
}
}

重點,處理異常

protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,
@Nullable Object handler, Exception ex) throws Exception {
ModelAndView exMv = null;
// 判斷當前的異常解析器是否存在;也就是從容器中獲取所有HandlerExceptionResolver類型對象
// 這里我們就不展開了,你可以在DispatcherServlet中查看初始化過程
// 默認情況下,這里集合中有如下圖1中所示
if (this.handlerExceptionResolvers != null) {
// 遍歷每一個異常處理器,誰能返回ModelAndView就結(jié)束循環(huán)
// 由于DefaultErrorAttributes內(nèi)部方法直接返回了null,所以這里返回的是HandlerExceptionResolverComposite
// 這是聚合類,聚合了其它3個具體的解析器,所以時間處理的還是其它類并非它
for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {
// 結(jié)合上面說只考慮RequestMappingHandlerMapping處理Controller的情況
// 那這里合理的解析器是ExceptionHandlerExceptionResolver
exMv = resolver.resolveException(request, response, handler, ex);
if (exMv != null) {
break;
}
}
}
// 通過上面的執(zhí)行如果獲取到了ModelAndView對象,下面就是判斷視圖對象不同的情況如何進行處理了
if (exMv != null) {
if (exMv.isEmpty()) {
request.setAttribute(EXCEPTION_ATTRIBUTE, ex);
return null;
}
if (!exMv.hasView()) {
String defaultViewName = getDefaultViewName(request);
if (defaultViewName != null) {
exMv.setViewName(defaultViewName);
}
}
WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());
// 如果存在要想前端展示的視圖,則返回。
return exMv;
}
throw ex;
}

圖1(這里的CustomExceptionResolver是我自定義的,大家可以忽略)

默認HandlerExceptionResolver集合

根據(jù)ExceptionHandlerExceptionResolver 的繼承關(guān)系得到核心處理邏輯是如下方法:

protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request,
HttpServletResponse response, @Nullable HandlerMethod handlerMethod, Exception exception) {
// 這里的整個過程會先從Controller中獲取所有@ExceptionHandler標注的方法中獲取能夠
// 處理該異常的方法,如果沒有會從全局異常句柄中查找
ServletInvocableHandlerMethod exceptionHandlerMethod = getExceptionHandlerMethod(handlerMethod, exception);
if (exceptionHandlerMethod == null) {
return null;
}
// ...
ServletWebRequest webRequest = new ServletWebRequest(request, response);
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
ArrayList<Throwable> exceptions = new ArrayList<>();
// 下面的流程就是執(zhí)行上面的ServletInvocableHandlerMethod
try {
// Expose causes as provided arguments as well
Throwable exToExpose = exception;
while (exToExpose != null) {
exceptions.add(exToExpose);
Throwable cause = exToExpose.getCause();
exToExpose = (cause != exToExpose ? cause : null);
}
Object[] arguments = new Object[exceptions.size() + 1];
exceptions.toArray(arguments); // efficient arraycopy call in ArrayList
arguments[arguments.length - 1] = handlerMethod;
// 執(zhí)行方法調(diào)用(執(zhí)行@ExceptionHandler標注的方法,這方法執(zhí)行過程中可能就直接向客戶端返回數(shù)據(jù)了,比如基于Rest接口)
exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, arguments);
} catch (Throwable invocationEx) {
// ...
return null;
}

if (mavContainer.isRequestHandled()) {
return new ModelAndView();
} else {
// 構(gòu)建ModelAndView對象
ModelMap model = mavContainer.getModel();
HttpStatus status = mavContainer.getStatus();
ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, status);
mav.setViewName(mavContainer.getViewName());
if (!mavContainer.isViewReference()) {
mav.setView((View) mavContainer.getView());
}
if (model instanceof RedirectAttributes) {
Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();
RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);
}
return mav;
}
}

上面大體上就是Controller發(fā)生異常后的處理邏輯。

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2011-07-21 15:20:41

java異常處理機制

2009-06-18 14:00:51

2009-09-28 10:39:01

Hibernate基礎(chǔ)

2009-09-25 14:23:39

2010-04-26 18:17:19

Oracle存儲過程

2009-12-03 17:41:40

PHP應(yīng)用發(fā)展

2021-10-25 19:52:52

IntentFilte

2009-09-09 09:48:43

Linq延遲加載

2009-10-10 13:52:57

VB Update方法

2009-09-14 16:21:34

LINQ To XML

2009-09-14 13:50:35

LINQ編程模型

2010-01-06 13:50:37

.NET Framew

2009-11-20 13:11:44

Oracle XML數(shù)

2009-09-08 15:56:50

Linq使用Group

2011-03-17 09:20:05

異常處理機制

2010-01-06 16:12:52

分析Json stri

2010-04-12 10:53:07

Oracle SQL

2010-03-08 17:18:46

Linux du命令

2010-07-02 11:19:31

IP協(xié)議頭格式

2010-04-26 14:32:21

Oracle SQL
點贊
收藏

51CTO技術(shù)棧公眾號

久久免费在线观看| 色综合久久久久久久久久久| 91精品国产高清久久久久久91裸体 | 国产精品腿扒开做爽爽爽挤奶网站| 亚洲国产小视频| 日本888xxxx| 18视频在线观看网站| 91视频在线观看免费| 国产日韩欧美电影在线观看| 麻豆成人在线视频| 国产精品一区二区av交换| 欧美一区二区精品在线| 北条麻妃在线观看| 九色porny在线| 91一区二区三区在线播放| 国产免费亚洲高清| 日韩av片在线播放| 99精品视频在线观看免费播放| 亚洲第一二三四五区| 人人爽人人av| 欧美freesex黑人又粗又大| 国产精品久久久久久户外露出| 99re视频| 在线观看xxxx| 午夜在线a亚洲v天堂网2018| 精品国产一区二区三区久久狼5月| 熟妇人妻久久中文字幕| 天天综合91| 在线亚洲+欧美+日本专区| 日本黄大片在线观看| av影片在线看| 91色九色蝌蚪| 粉嫩精品一区二区三区在线观看| jizz国产在线| 先锋影音久久久| 欧美夫妻性生活视频| 毛片久久久久久| 蜜桃成人av| 亚洲精品国产成人| 亚洲av无码成人精品区| 成人在线中文| 色婷婷综合久久久久中文| bt天堂新版中文在线地址| 欧美18hd| 国产精品久久久久久亚洲毛片| 久久一区免费| 完全免费av在线播放| 日韩成人中文字幕| 亚洲一级Av无码毛片久久精品| 视频欧美精品| 欧美日韩国产高清一区二区三区| 久草综合在线观看| 亚洲精品一级二级| 欧美视频一二三| 99精品人妻少妇一区二区| 久草免费在线色站| 亚洲国产精品嫩草影院| 超碰人人爱人人| 羞羞的视频在线看| 亚洲摸摸操操av| 成人在线免费高清视频| 精品美女在线观看视频在线观看| 国产欧美精品国产国产专区 | 亚洲一级片免费观看| 亚洲欧美专区| 日韩视频免费观看高清完整版| 手机av在线免费| 国产高清日韩| 日韩一区二区中文字幕| 在线观看网站黄| 91精品导航| 亚洲精品99久久久久中文字幕| 国产伦精品一区三区精东| 久久影院资源站| 亚洲精品中文字幕女同| 制服 丝袜 综合 日韩 欧美| 欧美丝袜激情| 日韩网站免费观看高清| 2014亚洲天堂| 国产精品xvideos88| 98视频在线噜噜噜国产| 91久久国产综合久久91| 亚洲男人影院| 国产精品中文字幕久久久| 国产精品亚洲欧美在线播放| 成人一区二区视频| 欧美成ee人免费视频| www.av在线播放| 亚洲狼人国产精品| 日韩免费一级视频| 国产69精品久久| 日韩欧美一区电影| aaaaa级少妇高潮大片免费看| 欧美日韩伦理| 欧美黑人巨大精品一区二区| 国产午夜性春猛交ⅹxxx| 美女诱惑一区二区| 国产女人水真多18毛片18精品 | 国产肉丝袜一区二区| 国产又黄又爽免费视频| av免费不卡| 欧美日韩在线不卡| 精品久久久久一区二区| 精品国产乱码久久久久久蜜坠欲下| 久久久精品在线| 丰满少妇乱子伦精品看片| 麻豆精品新av中文字幕| 国产亚洲欧美一区二区| 婷婷成人激情| 欧美性videos高清精品| 日本黄色www| 精品国产一区二区三区av片| 欧美日韩成人在线视频| 亚洲成人av网址| 成人97人人超碰人人99| 久久免费视频2| 国产精品久久久久av电视剧| 日韩欧美国产午夜精品| 久久久精品成人| 国产日韩欧美一区在线| 91黄在线观看| 精品孕妇一区二区三区| 欧美视频一区在线观看| 少妇精品无码一区二区三区| 最新国产精品| 国产在线观看一区二区三区| 蜜桃视频在线观看网站| 亚洲最大成人综合| 不卡的在线视频| 精品产国自在拍| 欧美性视频精品| 亚洲精品久久久蜜桃动漫| 国产精品免费久久| 欧美精品aaaa| 九九精品久久| 97在线视频免费播放| 超碰福利在线观看| 亚洲男人电影天堂| 男人的天堂最新网址| 欧美午夜精彩| 国产精品网站视频| 黄视频在线播放| 欧美日韩免费一区| 性久久久久久久久久久| 亚洲第一伊人| 国产在线一区二区三区四区| 日本高清成人vr专区| 91精品在线免费| 91高清免费观看| 国产一区二区导航在线播放| 丰满女人性猛交| www欧美在线观看| 久久这里只有精品视频首页| 亚洲中文字幕在线一区| 国产精品水嫩水嫩| 五月天av在线播放| 国产韩日影视精品| 亚洲va欧美va国产综合剧情| av在线免费网址| 欧美不卡123| 日韩欧美亚洲视频| 久久久亚洲午夜电影| 一道本视频在线观看| 欧美日韩一二三四| 成人精品视频99在线观看免费| 日韩精品成人av| 欧美一区二区三区电影| 久久久全国免费视频| 成人精品小蝌蚪| 久草青青在线观看| 日韩精品一区二区三区免费观看| 成人a在线视频| gogo高清午夜人体在线| 精品一区二区三区四区| 国产无遮挡又黄又爽又色视频| 国产精品理论在线观看| 女王人厕视频2ⅴk| 国产一区二区三区久久| 亚洲国产精品一区在线观看不卡| 国产精品一区二区精品| 久久久在线视频| 国产资源在线看| 欧美一激情一区二区三区| 你懂的国产视频| 国产精品女主播av| 亚洲少妇一区二区| 美女日韩在线中文字幕| 自拍偷拍亚洲色图欧美| 高清精品视频| 国产精品小说在线| 男插女视频久久久| 亚洲天堂av在线播放| 精品人妻一区二区三区换脸明星| 午夜精品一区二区三区电影天堂| 先锋影音av在线| 国产风韵犹存在线视精品| 欧洲黄色一级视频| 香蕉久久网站| 欧美污视频久久久| 视频一区在线| 国产精品久久中文| 国内激情视频在线观看| 北条麻妃99精品青青久久| 亚洲 欧美 精品| 日韩一区二区在线播放| 综合网在线观看| 一区二区三区不卡在线观看| 小早川怜子久久精品中文字幕| 国产成人精品免费视频网站| 中文字幕永久视频| 在线成人国产| 免费成人深夜夜行网站视频| 九色精品国产蝌蚪| 国产精品推荐精品| 91精品网站在线观看| 国产www精品| 国产丝袜在线观看视频| 色偷偷综合社区| 欧美美女色图| 亚洲韩国青草视频| av中文字幕免费| 欧美日本一区二区三区| 一级黄色av片| 欧美日韩性视频| 久久精品www| 亚洲欧美激情视频在线观看一区二区三区| 性欧美丰满熟妇xxxx性仙踪林| 国产精品一级片在线观看| 亚洲欧美自偷自拍另类| 久久精品人人| 国产美女网站在线观看| 国内自拍视频一区二区三区| 在线视频不卡国产| 成人在线免费观看网站| 欧美主播一区二区三区美女 久久精品人| 99re6热只有精品免费观看| 成人免费网站在线| 亚洲在线资源| 日韩美女免费视频| 97se综合| 5566成人精品视频免费| 99爱在线视频| 55夜色66夜色国产精品视频| 美女的胸无遮挡在线观看| 国内精品美女av在线播放| 青春草在线视频| 欧美高清视频在线播放| av在线下载| 欧美精品videosex牲欧美| 尤物视频在线看| 欧美黄色免费网站| 美女网站视频在线| 欧美激情二区三区| 变态调教一区二区三区| 性欧美xxxx交| 免费一二一二在线视频| 欧美亚洲第一区| 欧美一区国产| 国产精品香蕉国产| 国产成人免费视频网站视频社区| 亚洲尤物视频网| 国产suv精品一区| 久久精品五月婷婷| 国产精品一区高清| 杨幂一区欧美专区| 欧美+日本+国产+在线a∨观看| av在线com| 国产精品人人爽人人做我的可爱| 日韩av资源在线| 蜜臂av日日欢夜夜爽一区| 永久av免费在线观看| 成人黄色网址在线观看| 精品无人区无码乱码毛片国产| 国产清纯在线一区二区www| 日本免费网站视频| 一区二区三区国产| wwwxxx亚洲| 欧美少妇bbb| 成人福利小视频| 亚洲欧美国产精品专区久久| 日本高清视频在线播放| 欧美国产日韩视频| 一区二区三区短视频| 国产伊人精品在线| 国产精品白浆| 亚洲7777| 亚洲国内自拍| 亚洲精品午夜在线观看| 国产91精品一区二区麻豆亚洲| 国产熟妇搡bbbb搡bbbb| 日韩一区欧美小说| 黄色片视频网站| 欧美精品一二三| 亚洲欧美自偷自拍| 日日噜噜噜夜夜爽亚洲精品 | 制服丝袜在线第一页| 久久久精品国产99久久精品芒果| 久久精品亚洲a| 欧美日韩中文在线| 国产男女猛烈无遮挡| 亚洲欧洲视频在线| 天堂av最新在线| 国产精品久久久久久久久免费看| 一区二区三区在线免费看| 日韩欧美精品久久| 亚洲小说欧美另类婷婷| 日本免费色视频| 久久精品一区二区| 国产在线观看99| 欧美高清视频不卡网| 日本一区高清| 欧美激情女人20p| 精品自拍视频| 欧美影视一区二区| 在线成人国产| 不卡的一区二区| 中文字幕色av一区二区三区| av网站中文字幕| 精品成人一区二区| 尤物视频在线看| 亚洲xxxx18| 欧美国产美女| 热久久精品免费视频| 99精品黄色片免费大全| www.av视频| 777午夜精品视频在线播放| 国产福利在线| 日韩免费观看高清| 日韩欧美黄色| 日本人体一区二区| 大白屁股一区二区视频| 免费在线观看一级片| 91精品国产综合久久久蜜臀图片 | 黄色欧美在线| 国产免费裸体视频| 国产成人福利片| 欧美老熟妇一区二区三区| 欧美日韩国产成人在线免费| 91精彩视频在线观看| 国产精品精品国产| 国产精品亚洲片在线播放| 免费黄色福利视频| 99久久久无码国产精品| 日操夜操天天操| 亚洲第一偷拍网| 欧美少妇网站| 久久久久se| 天堂成人免费av电影一区| 少妇按摩一区二区三区| 日韩欧美亚洲国产一区| 蜜芽tv福利在线视频| 国产精品久久久久久久久久ktv| 九九热线有精品视频99| 8x8x最新地址| 婷婷色在线播放| 国产亚洲日本欧美韩国| 最新日韩三级| 日韩欧美手机在线| 免费观看久久久4p| 精品亚洲乱码一区二区| 日韩一区二区高清| 2020国产在线| 蜜桃久久精品乱码一区二区| 日韩成人免费看| 日韩av毛片在线观看| 日韩一区二区免费在线观看| 国产三线在线| 欧美日韩精品一区| 青娱乐精品视频| 欧美精品一级片| 亚洲风情亚aⅴ在线发布| 在线天堂资源www在线污| 日本成人黄色| 激情图片小说一区| 国产无精乱码一区二区三区| 日韩国产精品一区| 嫩草伊人久久精品少妇av杨幂| 久久最新免费视频| 成人动漫一区二区三区| 日韩熟女一区二区| 久久精品在线视频| 欧洲亚洲一区二区三区| 91看片在线免费观看| 亚洲一级不卡视频| 毛片网站在线| 亚洲最大的成人网| 在线亚洲一区| 天天鲁一鲁摸一摸爽一爽| 亚洲国产精品热久久| 久久精品国产福利| 奇米影视亚洲色图| 国产欧美一区二区精品婷婷| www.狠狠干| 国产精品va在线播放| 国内视频精品| 人与动物性xxxx| 日韩精品中文字幕有码专区 | 欧美性色黄大片| 羞羞网站在线免费观看| 日本在线播放一区|