【问题标题】:Spring Boot in standalone Tomcat ignores exceptions set in DeferredResults独立 Tomcat 中的 Spring Boot 忽略 DeferredResults 中设置的异常
【发布时间】:2015-05-19 05:32:24
【问题描述】:

我正在独立 Tomcat 中运行 Spring Boot 1.2.1 应用程序。

我有两个控制器映射,为了简单起见,它们总是抛出异常。第一个是 GET 请求,它返回一个字符串作为视图名称:

    @RequestMapping(value = {
    "/index"
}, method = RequestMethod.GET)
public String init() throws MyRequestProcessingException {
    if (true) {
    throw new MyRequestProcessingException(
            "Something went wrong processing request");
    }
    return "init";
}

这是异常定义:

@ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR)
public class MyRequestProcessingException extends Exception {

public MyRequestProcessingException(String message) {
    super(message);
}   
}

在嵌入式 Tomcat 和独立 Tomcat 中,尝试访问 /index 总是会导致 500 并返回一些 JSON 错误数据给客户端。

我的控制器有另一个接受 POST 并返回 DeferredResult 的方法:

   @RequestMapping(value = "html/start", method = RequestMethod.POST, consumes = APPLICATION_FORM_URLENCODED)
public DeferredResult<String> start(final HttpServletResponse response,
                                    @Valid @ModelAttribute final InitialisationStartAttributes model,
                                    final SessionData sessionExisting) throws MyRequestProcessingException {
    final DeferredResult<String> finalResult = new DeferredResult<>(5000);

                // Just return an error, so we can test
                if (true) {
                    finalResult.setErrorResult(new MyRequestProcessingException(
                            "Something went wrong processing request"));
                }

    return finalResult;
}

在嵌入式 Tomcat 中,到 /html/start 的 POST 返回一个 500,响应正文中包含一些 JSON 数据,就像其他请求方法一样。但是,当我尝试使用独立的 Tomcat 实例重现此行为时,我总是得到 200 响应而没有响应主体。

我在嵌入式和独立的 Tomcat 7.0.52 中使用 Tomcat 8,但我也尝试使用独立的 Tomcat 8,但没有任何区别。

我的应用通过修改 /etc/tomcat/Catalina/localhost/ROOT.xml 部署在根应用上下文中。

编辑:我做了更多的测试,似乎 DeferredResult 是罪魁祸首。我还没有重写 handleErrorResult() 来看看会发生什么。不过我有点惊讶,因为我不记得在文档中看到任何关于在嵌入式和独立 Tomcat 中返回 DeferredResult 之间的区别。

【问题讨论】:

  • 一般来说它对我有用。也许您需要共享更多代码,例如您的控制器(引发异常的控制器和处理 /html/error 的控制器)?
  • 我已经编辑了这个问题,将看似两个不同的问题分开,并用进一步测试的结果对其进行了更新。我想将问题的焦点更改为如果我使用 @ResponseStatus 注释的异常而不尝试映射到自定义错误页面会发生什么,因为我已经删除了自定义错误页面并且仍然看到这种行为(仅在第二个控制器方法中)。

标签: java spring-mvc tomcat spring-boot http-status-codes


【解决方案1】:

如果您在@RequestMapping 中抛出异常并且不在任何地方处理它,那么在您点击ErrorPageFilter 之前不会设置响应状态。如果您想在自定义程序中将状态映射到错误路径,您需要处理错误并在某个位置获取过滤器链中设置的状态(例如,使用@ExceptionHandler 或使用Exception@ResponseStatus)。让您的自定义错误页面呈现的另一种方法是使用new ErrorPage(Exception.class, "/html/error") 映射异常而不是(或同时)HttpStatus

【讨论】:

  • 假设我不尝试配置自己的错误页面,而只是抛出一个带有 @ResponseStatus 注释的异常 - 在这种情况下,您希望 Tomcat 返回什么状态?
  • 我希望得到相同的状态(但在 Spring Boot 中这方面存在错误)。
  • 正如我在编辑中所指出的,问题似乎与使用 DeferredResults 有关。我不知道这是否符合预期 - 在我看来,我们应该能够配置一次并在嵌入式和独立 servlet 容器中运行它们。
  • 我怀疑是否有人用DeferredResult 测试过它。如果我是你,我会在 github 上打开一个问题:github.com/spring-projects/spring-boot/issues
【解决方案2】:

这种行为是由于 Spring Boot 的 ErrorPageFilter 中的错误造成的; see bug report on GitHub。它已在 Spring Boot 1.2.3 中修复。

【讨论】:

    猜你喜欢
    • 2016-07-29
    • 2015-12-28
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 2017-07-04
    相关资源
    最近更新 更多