java - 为什么Spring在处理端点异常时将RuntimeException包装在NestedServletException中?
问题描述
根据Servlet 规范:
servlet 或过滤器在处理请求期间可能会抛出以下异常:
- 运行时异常或错误
- ServletExceptions 或其子类
- IOExceptions 或其子类
如果我们看一下org.springframework.web.servlet.FrameworkServlet#processRequest
,我们会看到 Spring 抛出ServletException
and IOException
,但包装了其他的,包括RuntimeExceptions
:
try {
doService(request, response);
} catch (ServletException | IOException ex) {
failureCause = ex;
throw ex;
} catch (Throwable ex) {
failureCause = ex;
throw new NestedServletException("Request processing failed", ex);
}
为什么 Spring 不处理RuntimeException
like IOException
?
UPD:换句话说,如果他们以这种方式处理异常会发生什么错误:
try {
doService(request, response);
} catch (ServletException | IOException | RuntimeException ex) {
failureCause = ex;
throw ex;
} catch (Throwable ex) {
failureCause = ex;
throw new NestedServletException("Request processing failed", ex);
}
解决方案
doService
这是必需的,因为在内部调用的受保护抽象方法processRequest
可以抛出任何已检查或未检查Exception
的。
protected abstract void doService(HttpServletRequest request, HttpServletResponse response) throws Exception;
现在,假设您doService
像这样覆盖:
@Override
protected void doService(Long request, Long response) throws ClassNotFoundException {
// whatever ...
}
这将是完全合法的,但随后processRequest
可能会引发ClassNotFoundException
您必须将其声明为已检查异常的情况。并且因为processRequest
由和其他 API 方法使用doGet
,doPost
这些也必须声明ClassNotFoundException
,这违反了规范。
请注意,这主要适用于doService
不是由org.springframework.web.servlet.DispatcherServlet
. doService
在DispatcherServlet
调用中doDispatch
并且doDispatch
已经捕获了除ServletException
or之外的所有内容IOException
。但是,仍然需要再次捕获异常,因为 and 的声明doService
并doDispatch
没有将它们检查的异常列表限制为ServletException
and IOException
。
21/11/2019 编辑:
我认为您的替代异常处理约定没有任何问题。Indeed 更接近于字面解释的规范。该实现只是包装了所有不是 ServletException 或 IOException 的东西。这可能是因为稍后处理程序对异常类型敏感。但至少DispatcherServlet使用的DefaultHandlerExceptionResolver并非如此。
我看不到任何明显的问题,这可能会影响 web.xml 中的错误处理,使用<error-page><exception-type>...</exception-type></error-page>
或使用@Component
implementation ErrorPageRegistrar
。
推荐阅读
- prestashop - 如何将 PS_BASE_URI 应用于搜索模块?
- javascript - 无论连续 div 的最大大小如何,如何在网格中独立平铺 div?
- json - Azure ARM 模板 - DSC(新架构)未运行脚本且未返回错误?
- javascript - 在 componentWillUnmount 方法中取消所有订阅和异步任务
- python - ValueError:试图将“张量”转换为张量并失败。错误:参数必须是密集张量:
- c++ - 在向量插入期间引用绑定到空指针错误
- javascript - React - 带有对象的语义 ui 下拉菜单
- html - 我必须过滤没有 javascript 或 div 的图像:/
- java - 随机文本应用程序连续显示相同文本 2 次或更多次
- c++ - Poco/JSON 或 rapidjson 中的字符串到 JSON