我有一個控制器處理一些請求:
@RequestMapping(method = RequestMethod.POST, value = "/endpoint")
public ResponseEntity<MyResponse> myEndpoint(@RequestBody MyRequest request) throws Exception {
//...
}
這樣的控制器可能會拋出幾個例外,為此我使用@ExceptionHandler這種方式:
@ExceptionHandler(SomeSpecificException.class)
@ResponseBody
public ResponseEntity<Error> handleSomeSpeficicFailure(SomeSpecificException e) {
//handle specific exception
}
@ExceptionHandler(SomeOtherSpecificException.class)
@ResponseBody
public ResponseEntity<Error> handleSomeOtherSpeficicFailure(SomeOtherSpecificException e) {
//handle specific exception
}
//etc.
如果拋出的例外不屬于任何已知類,我添加了一個Exception.class回傳自定義 500的通用處理程式:
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseEntity<Error> handleUnknownFailure(Exception e) {
//handle unknown exception
}
做了一些測驗,它似乎作業正常。如果我拋出一個特定的例外,我會在特定的處理程式上呼叫,如果我拋出一個未映射的例外,我會在通用處理程式上呼叫。
但是,我沒有看到任何提及(無論是在 JavaDoc 中還是在 Spring 檔案中)關于我將首先在特定方法上被呼叫然后在泛型方法上被呼叫的保證。
如果 Spring 正在測驗一個特定的例外是instanceof Exception,那么它會是真的,所以它甚至可能首先在這個處理程式上呼叫我而不檢查其他的。
我的問題是:
- 有誰知道添加一個
@ExceptionHandler(Exception.class)來處理通用例外是否是一種好習慣?如果不是,那么正確的做法是什么? - 我怎樣才能保證類層次結構將得到尊重(例如,如果有一天我有
SomeVerySpecificException extends SomeSpecificException,Spring 怎么知道它必須在SomeSpecificException- 直接父級Exception- 祖父級之前呼叫我)?
uj5u.com熱心網友回復:
除錯后,我在他們的代碼中找到了答案——即使沒有記錄,也很遺憾。
@Nullable
private Method getMappedMethod(Class<? extends Throwable> exceptionType) {
List<Class<? extends Throwable>> matches = new ArrayList<>();
for (Class<? extends Throwable> mappedException : this.mappedMethods.keySet()) {
if (mappedException.isAssignableFrom(exceptionType)) {
matches.add(mappedException);
}
}
if (!matches.isEmpty()) {
matches.sort(new ExceptionDepthComparator(exceptionType));
return this.mappedMethods.get(matches.get(0));
}
else {
return null;
}
}
所以基本上對于給定的Exception,他們首先尋找所有那些映射的方法mappedException.isAssignableFrom(exceptionType)。
創建此串列后,然后:
- 如果串列為空,則回傳
null并讓默認錯誤處理 - 如果只包含一個元素,則回傳它
- 如果包含多個元素,則按深度(從最近到最遠的范圍)對它們進行排序并回傳第一個方法。
所以這個保證不是合同給的,而是在執行中,看起來確實做得很好。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/335985.html
上一篇:當資料庫在SpringBoot中具有其真實值時,API為某個欄位回傳0
下一篇:EXCEL表格對單元格的參考
