HTTP帖子身体虚假丢失(HttpURLConnection& Jetty)

时间:2012-10-11 17:14:01

标签: java http networking jetty httpurlconnection

我有一个家庭成长的协议,它使用HttpURLConnection(来自Java 1.6)& Jetty(6.1.26)将一个xml块作为请求POST并接收一个xml块作为响应。 xml的数量约为。 5KB。

当在世界不同地区的Linux EC2实例上运行发送方和接收方时,我发现在大约0.04%的请求中,Jetty处理程序将xml请求(帖子正文)视为空字符串。我已经检查过并且客户端输出它一直在尝试发送正确的(> 0长度)xml请求字符串。

我还通过在我的本地(Win 8)框中循环我的JUnit测试来重现这一点。

我认为错误必须是:

  • 滥用缓冲区
  • HttpURLConnection错误
  • 网络错误
  • Jetty bug
  • 我已经在代码
  • 中随机拍了一些愚蠢的事

相关代码如下:

客户端

        connection = (HttpURLConnection) (new URL (url)).openConnection();
        connection.setReadTimeout(readTimeoutMS);
        connection.setConnectTimeout(connectTimeoutMS);
        connection.setRequestMethod("POST");
        connection.setAllowUserInteraction(false);
        connection.setDoOutput(true);

        // Send request
        byte[] postBytes = requestXML.getBytes("UTF-8");
        connection.setRequestProperty("Content-length", "" + postBytes.length);
        OutputStream os = connection.getOutputStream();
        os.write(postBytes);
        os.flush();
        os.close();

        // Read response
        InputStream is = connection.getInputStream();
        StringWriter writer = new StringWriter();
        IOUtils.copy(is, writer, "UTF-8");
        is.close();
        connection.disconnect();
        return writer.toString();

SERVER(Jetty处理程序)

    public void handle(java.lang.String target, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, int dispatch) {
        InputStream is = request.getInputStream();
        StringWriter writer = new StringWriter();
        IOUtils.copy(is, writer, "UTF-8");
        is.close(); 
        String requestXML = writer.toString();
        // requestXML is 0 length string about 0.04% of time

有人能想到为什么我会将请求作为空字符串随机获取吗?

谢谢!

修改

我引入了一些更多的跟踪,并且当错误发生时,getContentLength()返回-1,但是客户端输出仍然显示它正在发送正确的字节数。

2 个答案:

答案 0 :(得分:2)

我想不出你为什么得到一个空字符串。代码看起来正确。如果您更新代码以检查空字符串,并且如果找到则报告请求的内容长度和传输编码,这将有助于识别罪魁祸首。 wirehark网络数据的痕迹也很好。

但最糟糕的是,码头6真的已经结束,我们不太可能更新它。如果你今天正在编写代码,那么你真的应该使用jetty-7或8.如果你是勇敢的话,甚至可以使用jetty-9里程碑版本。如果你在jetty-9中发现了这样的错误,我会把它当作一个试图为你修复它的皮疹!

答案 1 :(得分:1)

确保设置connection.setRequestProperty("Content-Type", "application/xml");如果没有某些内容类型,可能会丢弃POST数据。当我在本地复制您的问题(针对Grails嵌入式Tomcat实例)并提供此修复它时就是这种情况。