sendError()
Spring MVC
应用处理某个请求时遇到异常的话,除非开发人员明确地指定使用setStatus()
,否则都是面向sendError()
的处理流程,总的来说该处理流程概括如下 :
1.请求 requestB
处理逻辑或者Spring MVC
框架中发生异常 e
;
- 这里的处理逻辑指的是应用开发人员提供的请求处理控制器方法;
Spring MVC
框架指的是Spring MVC
框架的通用过滤器,拦截器等;
2.请求 requestB
处理逻辑/Spring MVC
框架/Servlet
容器捕获所发生的 异常 e
, 将 e
设置为请求requestB
的属性, 并决定响应responseB
的HTTP
状态码,然后返回Servlet
容器;
- 响应
HTTP
状态码的决定是由异常e
捕获者决定; - 如果是请求处理控制器逻辑捕获了异常,可以使用
responseB.setStatus()
,也可以使用responseB.sendError()
,这里仅考虑使用了responseB.sendError()
的情况; - 如果是
Spring MVC
框架捕获了异常,则会调用responseB.sendError()
; - 如果是
Servlet
容器捕获了异常,则会使用HTTP
状态码500
,此处相当于调用responseB.sendError(500)
- 请求
requestB
上会被添加属性javax.servlet.error.exception
–Throwable
, 异常e
3.Servlet
容器构造并转发forward(requestB,responseB)
请求到一个错误处理页面 requestE
Servlet
首先检测responseB.isErrorReportRequired()
属性,因为以上步骤调用了sendError()
,所以该属性为true
- 注意此时
requstB
带有属性指向异常e
,并且此时responseB
中的HTTP
状态码已经指定; Servlet
容器会获取异常e
的信息和所指定的HTTP
状态码,并继续在requstB
上添加如下属性 :javax.servlet.error.status_code
–Integer
, 所指定的HTTP
状态码;javax.servlet.error.message
–String
, 由sendError()
参数指定的错误信息;javax.servlet.error.servlet_name
–String
, 异常e
发生所在Servlet
的名称;javax.servlet.error.request_uri
–String
,异常e
发生时所请求的URI
路径;
- 错误处理请求页面的处理逻辑处理
requestE
, 获取以上步骤设置到requestB
的属性,组织并展示错误信息页面给客户端
setStatus()
从上面sendError()
的处理流程来看,请求requestB
的控制器逻辑如果捕获到异常e
,开发人员可能会使用setStatus()
而不是sendError()
向浏览器端返回结果。那么,setStatus()
的和sendError()
的区别是什么呢?首先,根据两个方法的实现逻辑,可以简单这么认为:
response.sendError(status,message) = response.setError() + response.setSatus(status) + response.setMessage(message)
该公式中的response.setError()
是导致response.isErrorReportRequired()
属性为true
从而触发转发到错误处理页面的根本原因。
所以,如果开发人员使用了setStatus()
而不是sendError()
,其处理流程相当于上面sendError()
处理流程中没有重定向到错误页面的部分,而是直接返回错误码给浏览器端。