SpringMVC異常處理句柄這些細(xì)節(jié),你知道嗎?
回顧
@Controller和@ControllerAdvice類可以使用@ExceptionHandler注解標(biāo)注方法來處理控制器方法的異常,如下例所示:
局部異常處理
全局異常處理
指定能處理的異常類型
在@ExceptionHandler中指明能夠處理的異常類。
以上是回顧了SpringMVC異常處理的基本使用,通過@ExceptionHandler注解標(biāo)注方法,在上面的方法中都接受的是異常類,那這方法可以接收什么樣的參數(shù)及返回值呢?
異常句柄參數(shù)
@ExceptionHandler方法支持以下參數(shù):
方法參數(shù) | 描述 |
Exception type | 用于訪問引發(fā)的異常。 |
HandlerMethod | 用于訪問引發(fā)異常的控制器方法。 |
WebRequest, NativeWebRequest | 對請求參數(shù)、請求和會話屬性的通用訪問,而不直接使用 Servlet API。 |
javax.servlet.ServletRequest, javax.servlet.ServletResponse | 選擇任何特定的請求或響應(yīng)類型(例如,ServletRequest或HttpServletRequest或Spring的MultipartRequest或MultipartHttpServletRequest)。 |
javax.servlet.http.HttpSession | 強(qiáng)制會話的存在。因此,這樣的參數(shù)永遠(yuǎn)不會為空。注意,會話訪問不是線程安全的。如果允許多個請求并發(fā)訪問一個會話,可以考慮將RequestMappingHandlerAdapter實例的synchronizeOnSession標(biāo)志設(shè)置為true。 |
java.security.Principal | 當(dāng)前已驗證的用戶-如果已知,可能是特定的Principal實現(xiàn)類。 |
HttpMethod | 請求的HTTP方法。 |
java.util.Locale | 當(dāng)前請求區(qū)域設(shè)置,由可用的最特定的LocaleResolver確定——實際上是配置的LocaleResolver或LocaleContextResolver。 |
java.util.TimeZone, java.time.ZoneId | 與當(dāng)前請求關(guān)聯(lián)的時區(qū),由LocaleContextResolver確定。 |
java.io.OutputStream, java.io.Writer | 用于訪問由Servlet API公開的原始響應(yīng)體。 |
java.util.Map, org.springframework.ui.Model, org.springframework.ui.ModelMap | 用于訪問錯誤響應(yīng)的模型??偸强盏?。 |
RedirectAttributes | 指定在重定向情況下使用的屬性-(將被追加到查詢字符串中)和臨時存儲的flash屬性,直到重定向后的請求。請參見重定向?qū)傩院虵lash屬性。 |
@SessionAttribute | 對于任何會話屬性的訪問,與作為類級@SessionAttributes聲明的結(jié)果存儲在會話中的模型屬性相反。更多細(xì)節(jié)請參見@SessionAttribute。 |
@RequestAttribute | 用于訪問請求屬性。詳見@RequestAttribute。 |
異常句柄返回值
@ExceptionHandler方法支持以下返回值:
返回值 | 描述 |
@ResponseBody | 返回值通過HttpMessageConverter實例轉(zhuǎn)換并寫入響應(yīng)??吹紷ResponseBody。 |
HttpEntity<B>, ResponseEntity<B> | 返回值指定通過HttpMessageConverter實例轉(zhuǎn)換完整響應(yīng)(包括HTTP報頭和正文)并將其寫入響應(yīng)??吹絉esponseEntity。 |
String | 要用ViewResolver實現(xiàn)解析的視圖名稱,并與隱式模型一起使用——通過命令對象和@ModelAttribute方法確定。處理程序方法還可以通過聲明model參數(shù)(前面描述過)以編程方式豐富模型。 |
View | 一個用于呈現(xiàn)隱式模型的View實例——通過命令對象和@ModelAttribute方法確定。處理程序方法還可以通過聲明model參數(shù)(前面描述過)以編程方式豐富模型。 |
java.util.Map, org.springframework.ui.Model | 屬性被添加到隱式模型中,視圖名通過RequestToViewNameTranslator隱式確定。 |
@ModelAttribute | 添加到模型中的屬性,通過RequestToViewNameTranslator隱式確定視圖名。 注意@ModelAttribute是可選的。請參閱該表末尾的“任何其他返回值”。 |
ModelAndView object | 要使用的視圖和模型屬性以及(可選的)響應(yīng)狀態(tài)。 |
void | 具有void返回類型(或空返回值)的方法,如果它還具有ServletResponse、OutputStream參數(shù)或@ResponseStatus注釋,則認(rèn)為它已經(jīng)完全處理了響應(yīng)。如果控制器已經(jīng)做了一個正的ETag或lastModified時間戳檢查(詳情請參閱Controllers),同樣也是正確的。 如果以上都不為真,void返回類型也可以表示REST控制器的“無響應(yīng)體”或HTML控制器的默認(rèn)視圖名稱選擇。 |
Any other return value | 如果返回值與上述任何一個都不匹配,并且不是簡單類型(由BeanUtils#isSimpleProperty決定),默認(rèn)情況下,它將被視為要添加到模型中的模型屬性。如果是簡單類型,則仍未解決。 |
REST API異常
REST服務(wù)的一個常見需求是在響應(yīng)體中包含錯誤詳細(xì)信息。Spring框架不會自動執(zhí)行此操作,因為響應(yīng)體中的錯誤細(xì)節(jié)表示是特定于應(yīng)用程序的。但是,@RestController可以使用帶有ResponseEntity返回值的@ExceptionHandler方法來設(shè)置響應(yīng)的狀態(tài)和主體。這樣的方法也可以在@ControllerAdvice類中聲明,以便全局應(yīng)用它們。
在響應(yīng)體中使用錯誤細(xì)節(jié)實現(xiàn)全局異常處理的應(yīng)用程序應(yīng)該考慮擴(kuò)展ResponseEntityExceptionHandler,它為Spring MVC引發(fā)的異常提供處理,并提供自定義響應(yīng)體的鉤子。要使用它,可以創(chuàng)建ResponseEntityExceptionHandler的子類,用@ControllerAdvice注釋它,重寫必要的方法,并將其聲明為Spring bean,如下:
ResponseEntityExceptionHandler類中內(nèi)置了很多類型的異常處理