java - 独立 Tomcat 中的 Spring Boot 会忽略 DeferredResults 中设置的异常

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

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

我有两个 Controller 映射,为了简单起见,它们总是抛出异常。第一个用于 GET 请求,它返回 View 名称的字符串:

    @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 错误数据。

我的 Controller 有另一个接受 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 8,在独立版中使用 Tomcat 7.0.52,但我也尝试过在独立版 Tomcat 8 中使用,但没有任何区别。

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

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

最佳答案

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

关于java - 独立 Tomcat 中的 Spring Boot 会忽略 DeferredResults 中设置的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29088066/

相关文章:

mysql - 无法设置 Hibernate + Spring + mysql + maven

connection - 如果应用程序崩溃,Java JRE 会关闭连接吗?

spring-mvc - 如何在 Spring Interceptor preHandle 方法中获取 Controller 方法名称

java - "Failed to load Main-Class manifest attribute from client.jar"在可能的恶意软件 .jar 文件中?

spring - 使用 spring-boot 创建企业 Maven 应用程序

apache - ClassNotFoundException 即使 jar 在 WEB-INF/lib 中

json - 如何使用默认 jar (tomcat-juli.jar) 在 json 中配置 Tomcat Catalina 日志

java - struts 2.3.16.1 升级为 Spring 框架中的 struts xwork 和 SimpleMessageListenerContainer 提供 TypeMismatchException

java - 如何获取存储在 google-cloud-storage 存储桶子目录中的图像的 URL

java - 在不访问应用程序的情况下获取 Dagger 组件