异常
@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
方法相同的返回值。