在抛出异常时使Struts发送500内部服务器错误

时间:2012-03-12 22:08:16

标签: struts http-response-codes

我正在开发一个支持AJAX的JavaScript前端,该前端调用使用Struts编写的Java后端。我的问题是,当后端抛出异常时,客户端仍然会看到“200 OK”HTTP响应代码,而不是像预期的那样“500内部服务器错误”。

这让我反复绊倒,因为我的第三方客户端JavaScript库依赖于HTTP状态代码来确定AJAX调用是否有问题,正如大多数现代库通常所做的那样。错误传递未检测到,直到我的代码在尝试解析通常为JSON的情况时爆炸。

我真的想避免黑客攻击我的客户端JS库,以便优雅地处理这些错误。那么,当后端出现未处理的异常时,如何让Struts为我提供500状态代码呢?这不应该是Struts的默认行为吗?

编辑:在这种情况下,客户端代码无关紧要。我需要修复服务器,以便在未处理的异常发生时发送相应的状态代码。谢谢!

4 个答案:

答案 0 :(得分:3)

我想出了一种方法。我不确定它是最好的还是最简单的,但它确实有效。我找到了Struts Exception Configuration guide并将以下内容添加到<package>内的struts.xml内:

<global-results>
  <result name="exception">/exception.jsp</result>
</global-results>

<global-exception-mappings>
  <exception-mapping exception="java.lang.Exception" result="exception" />
</global-exception-mappings>

这会导致所有未处理的异常重定向到/exception.jsp。以下是JSP的内容:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="application/json; charset=UTF-8" %>
<% response.setStatus(500); %>
{"success": false,"errors": "<s:property value="%{exception.message}"/>"}

您将在第3行注意到我手动将响应代码设置为500。

这给了我一个新问题:不再记录异常。正如前面提到的Struts指南中所建议的那样,我通过在<package>中添加以下内容struts.xml来解决这个问题:

<interceptors>
    <interceptor-stack name="appDefaultStack">
        <interceptor-ref name="defaultStack">
            <param name="exception.logEnabled">true</param>
             <param name="exception.logLevel">ERROR</param>
        </interceptor-ref>
    </interceptor-stack>
</interceptors>

<default-interceptor-ref name="appDefaultStack" />

Struts:-1用于制作如此简单明显的功能而不是默认功能,另外-1用于使解决方案如此钝。

答案 1 :(得分:3)

更新:我修复了<global-results>部分(缺少httpheader标记)

我更喜欢your solution,但如果您不想在jsp中设置响应标头,那么这是另一种方法。

  1. 在struts.xml中,创建一个从“java.lang.Exception”到名为“exception”的结果的全局异常映射
  2. 在struts.xml中,创建一个全局结果,将“exception”映射到值为500的httpheader结果。
  3. web.xml 中,创建一个错误页面条目,将错误代码500映射到您的错误页面位置。
  4. 因此,对于struts.xml:

    <global-exception-mappings>
        <exception-mapping exception="java.lang.Exception" result="exception" />
    </global-exception-mappings>
    
    <global-results>
        <result name="exception" type="httpheader">
            <param name="error">500</param>
        </result>
    </global-results>
    

    对于web.xml

    <error-page>
        <error-code>500</error-code>
        <location>/exception.jsp</location>
    </error-page>
    

    这有效,但有一些重大缺点。 servlet容器正在呈现您的错误页面(而不是struts),因此您将无法访问原始错误消息或struts valueStack。但是,异常日志记录仍然有效(如果已启用)。

    顺便说一句,我也觉得令人费解的是,struts使得这一点变得如此困难。在其他每个框架中,我都处理了返回错误页面的概念,错误代码实现起来非常简单。

答案 2 :(得分:0)

500内部服务器错误是服务器端错误,这意味着问题可能不在于您的计算机或Internet连接,而是网站服务器的问题。

有意在客户端处理此问题。它位于处理请求的Web服务器(HTTP服务器)上。

答案 3 :(得分:-1)

你没有提到你正在使用的JS库。我建议仔细阅读文档。如果它有某种回调方法,则必须有responseText以外的responseCode。每当服务器端发生某些验证异常时,也会传递错误消息。只是不要依赖抛出一些异常,因为你正在使用AJAX。您可以跟踪responseText以显示某些消息,例如“验证因此原因失败,请再试一次”。同意?

否则在提交响应之前抛出WebApplicationException

throw new javax.ws.rs.WebApplicationException();  // or by any other constructor

以下是jar