8

我正在开发一个支持 AJAX 的 JavaScript 前端,它调用用 Struts 编写的 Java 后端。我的问题是,当后端抛出异常时,客户端仍然会看到“200 OK”的 HTTP 响应代码,而不是预期的“500 Internal Server Error”。

这让我反复受挫,因为我的第 3 方客户端 JavaScript 库依赖 HTTP 状态代码来确定 AJAX 调用是否有问题,就像大多数现代库通常所做的那样。直到我的代码在尝试解析通常是 JSON 的内容时崩溃,这些错误才会被检测到。

为了优雅地处理这些错误,我真的想避免破解我的客户端 JS 库。那么,当后端出现未处理的异常时,如何让 Struts 给我一个 500 状态码呢?这不应该是 Struts 的默认行为吗?

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

4

4 回答 4

3

我想出了一种方法。我不确定它是最好的还是最简单的,但它确实有效。我找到了 Struts异常配置指南<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>的 in 中添加以下内容来解决这个问题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 用于使解决方案如此迟钝。

于 2012-03-15T16:26:57.987 回答
3

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

我更喜欢您的解决方案,但是如果您不想在 jsp 中设置响应标头,那么您可以使用另一种方法来做到这一点。

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

因此,对于 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 让这变得如此困难。在所有其他框架中,我都处理了返回错误页面的概念,并且错误代码实现起来非常简单。

于 2013-03-25T20:43:19.717 回答
0

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

需要注意的是在客户端处理这个问题。它位于处理请求时配置的 Web 服务器(HTTP 服务器)上。

于 2012-12-18T09:47:50.047 回答
-1

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

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

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

这是罐子

于 2012-03-14T05:34:49.343 回答