自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

讓錯(cuò)誤處理重新由Web服務(wù)器接管

開(kāi)發(fā) 前端 服務(wù)器
讀過(guò)的小伙伴應(yīng)該能猜出來(lái)一些。因?yàn)镾pringMVC開(kāi)發(fā)的工程最終打成war包,然后扔到tomcat下面即可。而且SpringMVC和tomcat之間是通過(guò)Java Web的規(guī)范聯(lián)系起來(lái)的,它們之間根本沒(méi)有辦法自由交互的。

 其實(shí)web服務(wù)器是會(huì)處理錯(cuò)誤的

[[286622]]

在web.xml還是隨處可見(jiàn)的年代時(shí)(確實(shí)有點(diǎn)老黃歷了),下面的這些配置應(yīng)該都不陌生。

根據(jù)錯(cuò)誤代碼處理錯(cuò)誤,如下圖01:

 

根據(jù)異常類(lèi)型處理錯(cuò)誤,如下圖02:

 

不過(guò)我們更加熟悉的應(yīng)該是SpringMVC的統(tǒng)一異常處理。如下圖03:

 

看到@ControllerAdvice注解和@ExceptionHandler注解都應(yīng)該很熟悉吧。

處理原理就是在捕獲到業(yè)務(wù)Controller有異常拋出時(shí),根據(jù)異常類(lèi)型來(lái)這里找到對(duì)應(yīng)的方法并執(zhí)行。

可見(jiàn),整個(gè)異常的處理過(guò)程都是在SpringMVC內(nèi)部給搞定了,根本就沒(méi)有涉及到web服務(wù)器,如tomcat。

那么問(wèn)題來(lái)了,明明web服務(wù)器可以處理異常,為啥SpringMVC還要自己處理呢?

是不想呢,還是另有苦衷

讀過(guò)的小伙伴應(yīng)該能猜出來(lái)一些。因?yàn)镾pringMVC開(kāi)發(fā)的工程最終打成war包,然后扔到tomcat下面即可。

而且SpringMVC和tomcat之間是通過(guò)Java Web的規(guī)范聯(lián)系起來(lái)的,它們之間根本沒(méi)有辦法自由交互的。

然而tomcat的錯(cuò)誤處理需要在web.xml里面配置。嚴(yán)格來(lái)說(shuō),web.xml其實(shí)和SpringMVC關(guān)系不大。

特別是Spring全面進(jìn)入Java和注解配置時(shí)代以后,web.xml逐漸被弱化,繼而變得可有可無(wú),直到最終完全消失。

所以(我猜測(cè))SpringMVC可能不希望自己的用戶到一個(gè)和自己關(guān)系不大的web.xml里面配置一些和業(yè)務(wù)相關(guān)的異常處理映射。

所以只好自己把異常處理消化掉。不勞tomcat大駕。因此才有了SpringMVC統(tǒng)一處理異常。

重新讓web服務(wù)器來(lái)處理錯(cuò)誤

當(dāng)歷史來(lái)到了SpringBoot的時(shí)代,SpringBoot翻身做主成了入口,web服務(wù)器竟然成了一個(gè)組件。

SpringBoot可以操作web服務(wù)器的API,通過(guò)編程的方式,對(duì)web服務(wù)器進(jìn)行深度配置。

所以很多事情都變得容易起來(lái),比如錯(cuò)誤處理。

因?yàn)閣eb.xml里的錯(cuò)誤處理映射最終是注冊(cè)到tomcat里面了,所以SpringBoot只要操作tomcat的API,使用編程的方式也來(lái)注冊(cè)一些錯(cuò)誤處理映射不就可以了嘛。

因?yàn)橛脩糁苯邮呛蚐pringBoot打交道的,所以SpringBoot需要抽象出一套錯(cuò)誤處理注冊(cè)機(jī)制,讓用戶來(lái)注冊(cè)。

這樣SpringBoot拿到用戶注冊(cè)的錯(cuò)誤處理映射信息后,在生成web服務(wù)器(如tomcat)時(shí),把這些映射信息添加到web服務(wù)器中即可。

SpringBoot注冊(cè)錯(cuò)誤處理映射的方案

先來(lái)看看錯(cuò)誤處理映射是如何描述的,如下圖04:

 

三個(gè)字段的含義是:

path是一個(gè)路徑,它表示的是錯(cuò)誤處理的url。

status是一個(gè)狀態(tài)碼,如404、500等。

exception是一個(gè)異常類(lèi)型,如LoginFailedException。

一共有三種使用方式:

1)status + path,如404 + /404,表示如果遇到了404,就去執(zhí)行/404這個(gè)url。

2)exception + path,如LoginFailedException + /loginfailed,表示如果遇到登陸失敗異常,就去執(zhí)行后面這個(gè)url

3)沒(méi)有status和exception,只有path,這相當(dāng)于通配符,匹配所有異常情況。

接下來(lái)就該考慮如何注冊(cè)了,照例給個(gè)接口就行了,如下圖0506:

 

Spring是以bean打天下的,所以SpringBoot給的方法當(dāng)然也是和bean相關(guān)。

只要向容器中注冊(cè)一個(gè)該接口類(lèi)型的bean即可,如下圖07:

 

這些信息會(huì)被收集到并存好,如下圖08:

 

然后在創(chuàng)建web服務(wù)器時(shí)添加進(jìn)去就行了,以tomcat為例,如下圖09:

 

可以看到最終轉(zhuǎn)換為tomcat的錯(cuò)誤映射,如下圖10:

 

這里的setLocation、setErrorCode、setExceptionType三個(gè)setter方法,就對(duì)應(yīng)于web.xml里的、這三個(gè)標(biāo)簽。

至此,錯(cuò)誤處理已經(jīng)被注冊(cè)好了。

SpringBoot仍需協(xié)助處理錯(cuò)誤

有一點(diǎn)需要明白,SpringMVC交給tomcat的只是錯(cuò)誤處理映射的匹配工作,但有些真正的錯(cuò)誤處理還是要自己做的。

所以整個(gè)過(guò)程是這樣的,SpringMVC隨意拋出異常,這個(gè)異常會(huì)被拋到tomcat里面,tomcat獲取異常類(lèi)型并根據(jù)注冊(cè)的錯(cuò)誤處理映射關(guān)系找到一個(gè)url,然后調(diào)用這個(gè)url。

那么請(qǐng)問(wèn)這個(gè)url指向哪里呢?很大概率又回到了SpringMVC里面了,是不是很有意思,哈哈。

tomcat就像一面鏡子,SpringMVC向它發(fā)射了一束光線,經(jīng)過(guò)反射后又回來(lái)了。只不過(guò)發(fā)射的是一個(gè)異常,回來(lái)的是一個(gè)url。

這個(gè)url對(duì)應(yīng)的是能夠處理這個(gè)錯(cuò)誤的一個(gè)Controller的方法。這樣執(zhí)行這個(gè)Controller方法就等于處理了異常。

這個(gè)Controller是一個(gè)能夠處理錯(cuò)誤的Controller,所以就叫ErrorController。如下圖11:

 

其實(shí)它主要是一個(gè)Marker接口,也就起一個(gè)標(biāo)志作用。

下面是真正用于處理錯(cuò)誤的Controller,實(shí)現(xiàn)了剛剛的標(biāo)志接口,如下圖12:

 

@RequestMapping方法就是處理錯(cuò)誤的,既可以返回JSON,也可以返回視圖頁(yè)面。

我們可以自己寫(xiě)一個(gè)錯(cuò)誤處理類(lèi),然后繼承這個(gè)類(lèi),添加自己的錯(cuò)誤處理方法,最后使用@Controller注解重新注冊(cè)即可。

可以把一個(gè)異常映射成和它名稱一樣的url路徑,如把Exception映射為/Exception,如下圖13:

 

這兩個(gè)方法,一個(gè)返回html頁(yè)面,一個(gè)返回一個(gè)JSON。

備注:異常類(lèi)型和它映射的url之間的關(guān)系,可以按自己的需求去規(guī)劃,統(tǒng)一規(guī)則即可。

處理錯(cuò)誤時(shí),自然要獲得錯(cuò)誤相關(guān)信息才行,這個(gè)接口可以滿足,如下圖14:

 

可以獲得錯(cuò)誤屬性和拋出的異常對(duì)象。

可以看到接口的兩個(gè)方法都有WebRequest這個(gè)參數(shù),說(shuō)明錯(cuò)誤信息是從request中獲取出來(lái)的。

同時(shí)也說(shuō)明有些錯(cuò)誤信息是有人專(zhuān)門(mén)放入request中的,是SpringBoot放的,還是web服務(wù)器放的?

其實(shí)都有,比如異常對(duì)象是SpringBoot放的,響應(yīng)狀態(tài)碼是web服務(wù)器(按Java web規(guī)范)放的。

這也說(shuō)明web服務(wù)器執(zhí)行錯(cuò)誤處理的url時(shí)用的是轉(zhuǎn)發(fā)(forward)而非重定向(redirect),因?yàn)橐A魊equest中的信息。

還剩最后一個(gè),錯(cuò)誤視圖解析器,如下圖15:

 

SpringBoot自己提供了默認(rèn)的視圖解析器實(shí)現(xiàn),默認(rèn)去classpath下面的error目錄下尋找.html視圖頁(yè)面。

如下圖16:

 

支持狀態(tài)碼到頁(yè)面的映射,如404默認(rèn)映射為/error/404.html,500默認(rèn)映射為/error/500.html。

如果沒(méi)有這么具體的頁(yè)面,還支持系列映射,如404映射為/error/4xx.html,500映射為5xx.html。

當(dāng)然,默認(rèn)的一般都無(wú)法滿足需求,我們可以繼承這個(gè)默認(rèn)的類(lèi),然后重寫(xiě)視圖解析方法。

最后把這個(gè)類(lèi)注冊(cè)為bean即可,這樣SpringBoot就會(huì)使用我們的類(lèi)了。如下圖17:

 

本文總結(jié),重要

1)用戶使用SpringBoot提供的錯(cuò)誤處理映射機(jī)制注冊(cè)狀態(tài)碼和異常的映射url信息。

2)這些映射信息最終會(huì)被注冊(cè)進(jìn)web服務(wù)器中,如tomcat。

3)SpringBoot把異常拋給web服務(wù)器,web服務(wù)器根據(jù)異常找到對(duì)應(yīng)的url,并執(zhí)行它。

4)流程再次回到SpringBoot中,進(jìn)入錯(cuò)誤處理Controller的方法中,執(zhí)行錯(cuò)誤處理方法。

5)如果需要解析視圖的,使用錯(cuò)誤視圖解析器進(jìn)行視圖解析。否則就是直接返回JSON。

其中用戶能參與的就三步,注冊(cè)異常映射,擴(kuò)展錯(cuò)誤處理Controller,擴(kuò)展錯(cuò)誤視圖解析器。

具體參與方式文章中都有,無(wú)非就是實(shí)現(xiàn)接口或繼承某個(gè)類(lèi),然后注冊(cè)為bean即可。

責(zé)任編輯:武曉燕 來(lái)源: 編程新說(shuō)
相關(guān)推薦

2024-03-27 08:18:02

Spring映射HTML

2010-01-06 14:08:33

JSON WEB站點(diǎn)

2010-05-18 17:13:11

IIS服務(wù)器

2021-04-14 07:08:14

Nodejs錯(cuò)誤處理

2010-07-20 13:29:30

Telnet服務(wù)器

2010-05-18 16:35:35

Web服務(wù)器訪問(wèn)失敗

2022-11-16 08:41:43

2014-11-17 10:05:12

Go語(yǔ)言

2009-08-05 16:04:50

2021-04-29 09:02:44

語(yǔ)言Go 處理

2023-10-28 16:30:19

Golang開(kāi)發(fā)

2010-06-01 16:14:04

2017-11-10 08:58:49

Web服務(wù)器應(yīng)用程序

2017-03-08 08:57:04

JavaScript錯(cuò)誤堆棧

2016-08-19 10:41:42

Swift 2錯(cuò)誤

2017-04-06 14:40:29

JavaScript錯(cuò)誤處理堆棧追蹤

2023-12-26 22:05:53

并發(fā)代碼goroutines

2015-08-19 14:11:56

SQL Server錯(cuò)誤處理

2011-05-25 10:26:42

ora-02069錯(cuò)誤

2019-02-26 16:20:52

FTP服務(wù)器
點(diǎn)贊
收藏

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