Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Spring中发生异常后设置(http)状态代码(非500)_Java_Spring_Spring Mvc_Exception Handling - Fatal编程技术网

Java 在Spring中发生异常后设置(http)状态代码(非500)

Java 在Spring中发生异常后设置(http)状态代码(非500),java,spring,spring-mvc,exception-handling,Java,Spring,Spring Mvc,Exception Handling,正如标题所示,我希望在发生异常后更改http状态。 简短的背景是,为了能够显示错误页面,我需要向客户端发送状态代码200。(在错误状态代码上,它转储数据并显示一般错误弹出窗口) 为了测试这一点,我有: @RequestMapping(value= "/err") public String throwError() { throw new IllegalStateException(); } 在web xml中: <error-p

正如标题所示,我希望在发生异常后更改http状态。 简短的背景是,为了能够显示错误页面,我需要向客户端发送状态代码200。(在错误状态代码上,它转储数据并显示一般错误弹出窗口)

为了测试这一点,我有:

    @RequestMapping(value= "/err")
    public String throwError()
    {
        throw new IllegalStateException();
    }

在web xml中:

    <error-page>
        <error-code>500</error-code>
        <location>/errorPage</location>
    </error-page>

catalina日志输出为200,但客户端中的响应为:

加载资源失败:服务器响应状态为500(内部服务器错误)

Spring将异常编码为状态码500(我想它在HandlerExceptionResolver链中?),然后调用我的errorPage控制器。 Spring似乎记得抛出了一个异常,并在控制器返回后忽略(或重新编码?)状态代码为500

令人困惑的是(也许不是?)如果我从errorPage控制器返回一个响应实体并设置状态代码,这将得到尊重。例如:

    return new ResponseEntity(HttpStatus.ACCEPTED);
我想这不是一个bug,而是一个特性,Spring比我更清楚,我真的应该改变我实现这一切的方式。(!!?)

我不能只返回一个ResponseEntity,因为我需要呈现错误页面。我想如果我努力在控制器中呈现页面并将其放入ResponseEntity以实现我想要的,我可以做到,但它似乎。。。错

除了返回ResponseEntity(并绕过将其重置为500的任何机制),还必须有一种方法来控制返回的状态代码。或者只是告诉框架不要将抛出的异常重新编码为状态代码500

为了完整起见,我尝试在HandlerExceptionResolver中设置状态代码,并返回ModelAndView,结果同样令人失望。(500) 我也尝试过@ControllerAdvice@ExceptionHandler。。同样的结果

从设置状态代码的控制器(或HandlerExceptionResolver)返回后会发生什么,以及如何禁用状态代码,有什么线索吗?
可能是我的配置中的某个未知设置导致了这种情况?

您可以使用以下代码设置状态代码

@RequestMapping(value= "/err")
public String throwError()
{
     throw new IllegalStateException(message,
                         errorCode);
}

使用自定义HandlerExceptionResolver,我也遇到了这个问题。我花了一个下午的时间研究源代码。据我所知,这是因为Tomcat的错误页面处理

如果查看org.apache.catalina.core.StandardHostValve.throwable()的源代码(Tomcat 7),您将看到此方法用500覆盖状态代码属性:

request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, Integer.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR)); setAttribute(RequestDispatcher.ERROR\u STATUS\u CODE,Integer.valueOf(HttpServletResponse.SC\u INTERNAL\u SERVER\u ERROR)); 此处理程序针对所有基于异常的错误页执行

我的变通方法很愚蠢。您可以在错误页面中重置响应状态代码(假设它是JSP)。在(JSP)错误页面顶部添加这一行应该可以:

<% response.setStatus(200); %> 如果需要使用自定义状态代码,可以在控制器中进行设置:

request.setAttribute("myStatusCode", statusCode); setAttribute(“myStatusCode”,statusCode); 然后在JSP中重新阅读:

<% response.setStatus(Integer.valueOf(request.getAttribute("myStatusCode").toString())); %> 但那就更傻了

我试图删除控制器中的exception request属性,这将触发Tomcat阀门中基于状态代码的错误处理:

request.removeAttribute(RequestDispatcher.ERROR_EXCEPTION); request.removeAttribute(RequestDispatcher.ERROR\u异常); 不幸的是,这不适用于Spring的DispatcherServlet:processHandlerException()在调用异常解析程序后重新设置所有缺少的错误属性(为什么?!?),从而强制阀门中的throwable()处理程序,从而忽略自定义状态代码


希望这有帮助。

你好,Akhil,谢谢你的回答。我想你可能误解了我的问题?IllegalStateException只是测试功能的一个示例。由于各种原因,应用程序中任何地方的任何代码都可能引发异常(它不是由我控制的)。。。但也就是说,您的意思是Spring以某种方式评估异常的原因,并将状态代码设置为500(如果为null)?这可能是合理的,但正如我所说的,我无法更改所有可能引发异常的代码…也许我可以捕获异常并重新引发另一个自定义异常。。。像ExceptionHandledReturnokeException一样,在新的异常中设置@ResponseStatus。。。谢谢你的主意,我会试试的!不似乎什么都不管用!我觉得这很令人惊讶。。在Spring中,异常处理这样的基本需求是如此的混乱和混乱,除此之外,还没有完全发挥作用。还是我遗漏了什么?我正在扩展DispatcherServlet并捕获那里的异常,并重定向到我的错误页面。。但这似乎太俗气了。。但我别无选择。。。 request.removeAttribute(RequestDispatcher.ERROR_EXCEPTION);