Spring MVC 应用中异常处理流程分析 : sendError() vs setStatus()

sendError()

Spring MVC应用处理某个请求时遇到异常的话,除非开发人员明确地指定使用setStatus(),否则都是面向sendError()的处理流程,总的来说该处理流程概括如下 :

1.请求 requestB 处理逻辑或者Spring MVC框架中发生异常 e;

  • 这里的处理逻辑指的是应用开发人员提供的请求处理控制器方法;
  • Spring MVC框架指的是Spring MVC框架的通用过滤器,拦截器等;

2.请求 requestB 处理逻辑/Spring MVC框架/Servlet容器捕获所发生的 异常 e , 将 e设置为请求requestB的属性, 并决定响应responseBHTTP状态码,然后返回Servlet容器;

  • 响应HTTP状态码的决定是由异常e捕获者决定;
  • 如果是请求处理控制器逻辑捕获了异常,可以使用responseB.setStatus(),也可以使用responseB.sendError(),这里仅考虑使用了responseB.sendError()的情况;
  • 如果是 Spring MVC 框架捕获了异常,则会调用responseB.sendError();
  • 如果是 Servlet 容器捕获了异常,则会使用HTTP状态码500,此处相当于调用responseB.sendError(500)
  • 请求 requestB 上会被添加属性javax.servlet.error.exceptionThrowable , 异常 e

3.Servlet 容器构造并转发forward(requestB,responseB)请求到一个错误处理页面 requestE

  • Servlet首先检测responseB.isErrorReportRequired()属性,因为以上步骤调用了sendError(),所以该属性为true
  • 注意此时requstB带有属性指向异常e,并且此时responseB中的HTTP状态码已经指定;
  • Servlet容器会获取异常e的信息和所指定的HTTP状态码,并继续在requstB上添加如下属性 :
    • javax.servlet.error.status_codeInteger, 所指定的HTTP状态码;
    • javax.servlet.error.messageString , 由sendError()参数指定的错误信息;
    • javax.servlet.error.servlet_nameString , 异常e发生所在Servlet的名称;
    • javax.servlet.error.request_uriString,异常e发生时所请求的URI路径;
  1. 错误处理请求页面的处理逻辑处理 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()处理流程中没有重定向到错误页面的部分,而是直接返回错误码给浏览器端。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值