Spring Boot & Spring MVC 異常處理的N種方法

NO IMAGE
1 Star2 Stars3 Stars4 Stars5 Stars 給文章打分!
Loading...

github:https://github.com/chanjarste…

參考文件:

Spring Boot 1.5.4.RELEASE Documentation

Spring framework 4.3.9.RELEASE Documentation

Exception Handling in Spring MVC

預設行為

根據Spring Boot官方文件的說法:

For machine clients it will produce a JSON response with details of the error, the HTTP status and the exception message. For browser clients there is a ‘whitelabel’ error view that renders the same data in HTML format

也就是說,當發生異常時:

如果請求是從瀏覽器傳送出來的,那麼返回一個Whitelabel Error Page

但是有一個URL除外:http://localhost:8080/return-text-plain

那麼你就能在日誌檔案裡發現這麼一個異常:

... TRACE 13387 --- [nio-8080-exec-2] .w.s.m.m.a.ServletInvocableHandlerMethod : Invoking 'org.springframework.boot.autoconfigure.web.BasicErrorController.error' with arguments [[email protected]]
... TRACE 13387 --- [nio-8080-exec-2] .w.s.m.m.a.ServletInvocableHandlerMethod : Method [org.springframework.boot.autoconfigure.web.BasicErrorController.error] returned [<500 Internal Server Error,{timestamp=Thu Nov 09 13:20:15 CST 2017, status=500, error=Internal Server Error, exception=me.chanjar.exception.SomeException, message=No message available, trace=..., path=/return-text-plain, {}>]
... TRACE 13387 --- [nio-8080-exec-2] .w.s.m.m.a.ServletInvocableHandlerMethod : Error handling return value [type=org.springframework.http.ResponseEntity] [value=<500 Internal Server Error,{timestamp=Thu Nov 09 13:20:15 CST 2017, status=500, error=Internal Server Error, exception=me.chanjar.exception.SomeException, message=No message available, trace=..., path=/return-text-plain, {}>]
HandlerMethod details: 
Controller [org.springframework.boot.autoconfigure.web.BasicErrorController]
Method [public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
...

要理解這個異常是怎麼來的,那我們來簡單分析以下Spring MVC的處理過程:

圖片描述

那麼這個問題怎麼解決呢?我會在自定義ErrorController裡說明。

自定義Error頁面

前面看到了,Spring Boot針對瀏覽器發起的請求的error頁面是Whitelabel Error Page

本章節程式碼在me.chanjar.boot.customerrorattributes,使用CustomErrorAttributesExample執行。

自定義ErrorController

在前面提到了curl http://localhost:8080/return-text-plain

loo/error-406

注意到這兩個異常都有@ResponseStatus註解,這個是註解標明瞭這個異常所對應的Status Code。
但是在loo/error-600

要了解為什麼就需要知道Spring MVC對於異常的處理機制,下面簡單講解一下:

Spring MVC處理異常的地方在DispatcherServlet.processHandlerException,這個方法會利用HandlerExceptionResolver來看異常應該返回什麼ModelAndView

總結:

沒有被HandlerExceptionResolverresolve到的異常會交給容器處理。已知的實現有(按照順序):

DefaultErrorAttributes,只負責把異常記錄在Request attributes中,name是org.springframework.boot.autoconfigure.web.DefaultErrorAttributes.ERROR

不過需要注意的是,無法通過ErrorViewResolver設定Status Code,Status Code由@ResponseStatus或者容器決定(Tomcat裡一律是500)。

本章節程式碼在me.chanjar.boot.customerrorviewresolver,使用CustomErrorViewResolverExample執行。

@ExceptionHandler 和 @ControllerAdvice

前面的例子中已經有了對@ControllerAdvice@ExceptionHandler的使用,這裡只是在做一些補充說明:

@ExceptionHandler配合@ControllerAdvice用時,能夠應用到所有被@ControllerAdvice切到的Controller

@ExceptionHandler在Controller裡的時候,就只會對那個Controller生效

附錄I

下表列出哪些特性是Spring Boot的,哪些是Spring MVC的:

FeatureSpring BootSpring MVC
BasicErrorControllerYes
ErrorAttributesYes
ErrorViewResolverYes
@ControllerAdviceYes
@ExceptionHandlerYes
@ResponseStatusYes
HandlerExceptionResolverYes

相關文章

程式語言 最新文章