异常
如果在请求映射期间发生异常或从请求处理器(例如 @Controller
)抛出异常,DispatcherServlet
会委托给一系列 HandlerExceptionResolver
Bean 来解析异常并提供替代处理,通常是错误响应。
下表列出了可用的 HandlerExceptionResolver
实现
HandlerExceptionResolver |
描述 |
---|---|
|
异常类名与错误视图名称之间的映射。适用于在浏览器应用中渲染错误页面。 |
解析 Spring MVC 抛出的异常并将其映射到 HTTP 状态码。另请参阅替代方案 |
|
|
解析带有 |
|
通过调用 |
解析器链
您可以在 Spring 配置中声明多个 HandlerExceptionResolver
Bean,并通过设置其 order
属性来形成异常解析器链。order
属性值越高,异常解析器的位置越靠后。
HandlerExceptionResolver
的约定规定它可以返回
-
指向错误视图的
ModelAndView
。 -
如果在解析器内部处理了异常,则返回空的
ModelAndView
。 -
如果异常仍未解决,则返回
null
,以便后续解析器尝试处理;如果异常最终仍未处理,则允许其冒泡到 Servlet 容器。
MVC Config 会自动声明内置的解析器,用于处理默认的 Spring MVC 异常、带有 @ResponseStatus
注解的异常以及支持 @ExceptionHandler
方法。您可以自定义或替换这个列表。
容器错误页面
如果任何 HandlerExceptionResolver
都未能解决异常,从而使其继续传播,或者如果响应状态被设置为错误状态(即 4xx、5xx),Servlet 容器可以渲染一个默认的 HTML 错误页面。要自定义容器的默认错误页面,您可以在 web.xml
中声明错误页面映射。以下示例展示了如何做到这一点:
<error-page>
<location>/error</location>
</error-page>
根据前面的示例,当异常冒泡或响应具有错误状态时,Servlet 容器会在容器内向配置的 URL(例如,/error
)发起 ERROR 调度。然后由 DispatcherServlet
对其进行处理,可能会将其映射到 @Controller
,该控制器可以实现为返回带有模型的错误视图名称,或者渲染 JSON 响应,如下例所示:
-
Java
-
Kotlin
@RestController
public class ErrorController {
@RequestMapping(path = "/error")
public Map<String, Object> handle(HttpServletRequest request) {
Map<String, Object> map = new HashMap<>();
map.put("status", request.getAttribute("jakarta.servlet.error.status_code"));
map.put("reason", request.getAttribute("jakarta.servlet.error.message"));
return map;
}
}
@RestController
class ErrorController {
@RequestMapping(path = ["/error"])
fun handle(request: HttpServletRequest): Map<String, Any> {
val map = HashMap<String, Any>()
map["status"] = request.getAttribute("jakarta.servlet.error.status_code")
map["reason"] = request.getAttribute("jakarta.servlet.error.message")
return map
}
}
Servlet API 不提供在 Java 中创建错误页面映射的方法。但是,您可以同时使用 WebApplicationInitializer 和一个最小的 web.xml 。 |