如果我愿意关闭连接,如何在分块的http响应中途报告错误?

时间:2008-10-09 20:47:56

标签: servlets

(参见相关问题:How do I report an error midway through a chunked http repsonse without closing the connection?

在我的情况下,#1的愿望是浏览器显示错误消息。无论多么缺乏信息。

关闭ServletResponse outputStream显然不起作用。即使我没有先关闭(在Tomcat 6.0.16上测试),也不会抛出异常。我认为我想要的是一个RST数据包,一个块中间的FIN,或者糟糕的块头。

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

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

3 个答案:

答案 0 :(得分:1)

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

第一部分:似乎没有办法说服我测试的应用服务器在“已提交”阶段之后将错误放到线路上。以下Servlet代码在套接字上生成合法的HTTP Chunked Transfer标头。有趣的是,在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的字母,则与精神相反。

答案 1 :(得分:0)

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

如果你真的必须,你可以用JavaScript来争论一些东西。当您遇到错误时,在关闭连接之前输出类似的内容:

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

您可能希望扩展脚本,但是您可以获得一般的想法。这假设发送回浏览器的是HTML页面,你没有在问题中指明。

答案 2 :(得分:0)

servlet API不允许它。提交响应后,响应代码已发送。您可以做的最好是关闭连接并记录错误。