例外
@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 方法相同的方法引數和回傳值,但與請求 Body 和 @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
註解都可以宣告多個可產生的媒體類型,錯誤處理階段的內容協商將決定要使用哪種內容類型。