Spring Boot教程(10) – 錯誤處理

若是你使用Spring Initializr新建一個web項目,運行並訪問他的話,由於沒有寫控制器,你會獲得一個錯誤頁面,告訴你請求路徑沒找到(404錯誤):html

頁面標題爲「Whitelabel Error Page」,直譯爲「白標錯誤頁」,啥是白標,知乎上我搜到了這個答案:web

White Label 意思是你開發了一個產品,而這個產品能夠根據其餘不一樣公司的品牌形象(品牌logo,品牌顏色,圖片等等)包裝成該公司自身的產品。spring

我覺着吧,「白標錯誤頁」的意思就是這個錯誤頁面是個樣板,你能夠根據本身的需求自定義錯誤頁面樣式。瀏覽器

錯誤頁面,能夠是靜態HTML文件,也能夠用模板引擎生成。網絡

Spring Boot的靜態內容,能夠放在類路徑下的static或者public或者resources或者 META-INF/resources目錄下。我一般選擇static目錄,這時候錯誤頁面須要放在static/error目錄下,文件後綴爲html,文件名爲它所表明的HTTP狀態碼,好比處理404錯誤的文件路徑爲static/error/404.html。若是你想讓錯誤頁面接受更多的狀態碼,能夠寫成4xx.html或者5xx.htmlmvc

若是你使用模板引擎生成錯誤頁面,文件須要放在類路徑下templates/error目錄,文件後綴根據不一樣的模板引擎而定,文件名依然是HTTP狀態碼。app

若是你對以上兩種自定義錯誤頁面的方式不太滿意,你能夠本身實現一個ErrorViewResolver類型的Bean,這個Bean用來處理如何將HTTP狀態碼和視圖對應:框架

Spring Boot的錯誤處理機制不只僅能夠展現網頁,也能夠返回JSON。你嘗試在命令行輸入命令curl localhost:8080能夠獲得相似下圖的錯誤信息。curl

一樣的錯誤,在瀏覽器和在終端(或者其餘非瀏覽器方式)的輸出是不同的。可是他們所包含的信息是同樣的。這些信息是由ErrorAttributes對象提供的,ErrorAttributes會根據網絡請求的信息,生成一個Map<String, Object>對象,上圖的JSON就是根據它生成的,「白標錯誤頁」也是根據它生成的。你要是想自定義Map裏的東西,那就本身實現ErrorAttributes,做爲Bean放到容器裏。它的默認實現是DefaultErrorAttributes,你能夠參考參考。spring-boot

自定義ErrorAttributes

還沒完,我們繼續深刻。

若是你的控制器方法在處理請求的時候異常了,那麼框架會將你的請求轉發(forward,不是redirect)到/error路徑。有個控制器是專門處理/error路徑請求的,叫作BasicErrorController,本文到從開頭到如今提到的全部東西的邏輯都在它的代碼裏,建議你讀一讀。這個/error路徑其實也是能夠改的,修改server.error.path屬性就行。錯誤處理機制實際上是由一個自動配置類ErrorMvcAutoConfiguration觸發生效的,BasicErrorControllerDefaultErrorAttributes都是在這個配置類裏建立的,在這裏,你還能找到「白標錯誤頁」的生成代碼。

若是Spring Boot默認的錯誤處理機制(即BasicErrorController)還不夠你用的,那就只能本身寫個控制器了。本身寫控制器,你返回給客戶端什麼東西都中。注意你的控制器還得實現ErrorController接口,這樣才能把BasicErrorController給替換掉,以下圖。

上面的代碼複用了server.error.path屬性。你經過handleError方法就能夠定製響應請求了,不論是返回頁面仍是JSON仍是其餘的,均可以搞。

到這裏還不能知足你對錯誤處理的須要?

上面說的都是Spring Boot的錯誤處理機制,其實Spring MVC還自帶了一些。在控制器裏,能夠添加一個方法並加上@ExceptionHandler註解,這樣無論控制器的哪一個請求處理方法出現了異常,都會到這個方法裏處理。

圖中的參數類型是Exception,能夠從它那裏獲取異常信息。不過它範圍有點大,你能夠在註解里加個參數,讓errorHandler方法接受的異常更具體一點。

你還能夠寫多個錯誤處理方法,每一個處理不一樣類型或者場景下的異常。錯誤處理方法的參數除了上面提到的Exception,還有不少能夠用,好比HttpMethodWebRequestModel等等,具體列表能夠查看官方文檔。錯誤處理方法的返回值跟請求處理方法(handler methods)的返回值也都差很少,好比ModelAndView、模板文件名字、ResponseEntity<>等等。

@ExceptionHandler結合@ControllerAdvice註解能夠處理全部控制器的異常。不過咱們先到這裏,稍後的文章再談他。

原文連接:fookwood.com/spring-boot…

相關文章
相關標籤/搜索