異常
@Controller 和 @ControllerAdvice 類可以包含 @ExceptionHandler 方法來處理來自控制器方法的異常。以下示例包含一個此類處理方法
-
Java
-
Kotlin
import java.io.IOException;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
@Controller
public class SimpleController {
@ExceptionHandler(IOException.class)
public ResponseEntity<String> handle() {
return ResponseEntity.internalServerError().body("Could not read file storage");
}
}
import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.ExceptionHandler
import java.io.IOException
@Controller
class SimpleController {
@ExceptionHandler(IOException::class)
fun handle() : ResponseEntity<String> {
return ResponseEntity.internalServerError().body("Could not read file storage")
}
}
異常可以匹配正在傳播的頂級異常(即直接丟擲的 IOException),也可以匹配頂級包裝異常中的直接原因(例如,包裹在 IllegalStateException 中的 IOException)。
對於匹配的異常型別,最好將目標異常宣告為方法引數,如上例所示。另外,註解宣告可以縮小要匹配的異常型別。我們通常建議在引數簽名中儘可能具體,並在透過相應順序優先順序排序的 @ControllerAdvice 上宣告您的主要根異常對映。有關詳細資訊,請參閱MVC 部分。
WebFlux 中的 @ExceptionHandler 方法支援與 @RequestMapping 方法相同的方法引數和返回值,但請求體和 @ModelAttribute 相關的方法引數除外。 |
Spring WebFlux 中對 @ExceptionHandler 方法的支援由 @RequestMapping 方法的 HandlerAdapter 提供。有關更多詳細資訊,請參閱DispatcherHandler。
媒體型別對映
除了異常型別,@ExceptionHandler 方法還可以宣告可生產的媒體型別。這允許根據 HTTP 客戶端請求的媒體型別(通常在“Accept”HTTP 請求頭中)來細化錯誤響應。
應用程式可以直接在註解上宣告可生產的媒體型別,對於相同的異常型別
-
Java
-
Kotlin
@ExceptionHandler(produces = "application/json")
public ResponseEntity<ErrorMessage> handleJson(IllegalArgumentException exc) {
return ResponseEntity.badRequest().body(new ErrorMessage(exc.getMessage(), 42));
}
@ExceptionHandler(produces = "text/html")
public String handle(IllegalArgumentException exc, Model model) {
model.addAttribute("error", new ErrorMessage(exc.getMessage(), 42));
return "errorView";
}
@ExceptionHandler(produces = ["application/json"])
fun handleJson(exc: IllegalArgumentException): ResponseEntity<ErrorMessage> {
return ResponseEntity.badRequest().body(ErrorMessage(exc.message, 42))
}
@ExceptionHandler(produces = ["text/html"])
fun handle(exc: IllegalArgumentException, model: Model): String {
model.addAttribute("error", ErrorMessage(exc.message, 42))
return "errorView"
}
在這裡,方法處理相同的異常型別,但不會被拒絕為重複。相反,請求“application/json”的 API 客戶端將收到 JSON 錯誤,而瀏覽器將獲得 HTML 錯誤檢視。每個 @ExceptionHandler 註解可以宣告多個可生產的媒體型別,錯誤處理階段的內容協商將決定使用哪種內容型別。
方法引數
@ExceptionHandler 方法支援與 @RequestMapping 方法相同的方法引數,只是請求體可能已被消費。
返回值
@ExceptionHandler 方法支援與 @RequestMapping 方法相同的返回值。