1

(请参阅相关问题:如何在不关闭连接的情况下通过分块 http 响应中途报告错误?

就我而言,#1 的愿望是让浏览器显示错误消息。无论多么缺乏信息。

关闭 ServletResponse outputStream 显然不起作用。即使我没有先关闭(在 Tomcat 6.0.16 上测试),也不会引发异常。我认为我想要的是 RST 数据包、块中间的 FIN 或格式错误的块标头。

之后,我可以担心各种浏览器的响应方式。

为澄清而编辑:这是用于文件下载,可能是几千兆字节的二进制数据。在我必须开始发送一些数据之前,我无法确定是否可以成功读取或解密所有数据。

4

3 回答 3

1

我自己的答案,经过研究。

第一部分:似乎没有办法说服我测试的应用程序服务器在“提交”阶段之后将错误放到线路上。以下 Servlet 代码会在套接字上生成合法的 HTTP 块传输标头。有趣的是,在 WebSphere 的情况下,一条错误消息被附加到流的末尾,位于结束标记之前。

public class Servlet extends HttpServlet {
    public static final int ARRAY_SIZE = 65536;
    private static final int SEND_COUNT = 100000;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException {

        String testData = "This is a fairly long piece of test text, running on and on and on, over and over.";

        final ServletOutputStream outputStream = response.getOutputStream();
        for (int i = 0; i < SEND_COUNT; ++i) {
            outputStream.println(testData);
        }
        throw new ServletException("Break it now");
    }
}

第二部分:即使应用程序服务器愿意将虚假数据写入线路或关闭套接字而不关闭零长度块,普通客户端也不会报告错误。IE7、FF3 和 cURL 不会报告块编码错误。这使得 HTTP 下载本质上是不可靠的,如果不是 HTTP 1.1 RFC 的文字,这也违背了精神。

于 2008-10-15T20:07:57.327 回答
0

我认为你的做法是错误的。在您确定是成功还是失败之前,似乎不实际开始发送数据会更简单。这样,如果需要,您可以在开始时发送错误消息,而不是发送无效的部分数据。

如果你真的需要,你也许可以用 JavaScript 解决一些问题。当您遇到错误时,在关闭连接之前输出如下内容:

<script type="text/javascript"> alert("Processing failed!"); </script>

您可能想要扩展脚本,但您会得到大致的想法。这是假设发送回浏览器的是 HTML 页面,您没有在问题中指定。

于 2008-10-09T21:29:04.137 回答
0

servlet API 不允许这样做。提交响应后,响应代码已发送。您能做的最好的事情就是关闭连接并记录错误。

于 2008-10-15T20:18:07.553 回答