我有一个自行开发的协议,它使用HttpURLConnection(来自Java 1.6)和Jetty(6.1.26)来发布一个xml块作为请求,并接收一个xml块作为响应 . xml的数量约为 . 5KB .
当在世界不同地区的Linux EC2实例上运行发送方和接收方时,我发现在大约0.04%的请求中,Jetty处理程序将xml请求(帖子正文)视为空字符串 . 我已经检查过并且客户端输出它一直在尝试发送正确的(> 0长度)xml请求字符串 .
我还通过在我的本地(Win 8)框中循环我的JUnit测试来重现这一点 .
我假设错误必须是这样的:
-
滥用缓冲区
-
HttpURLConnection错误
-
网络错误
-
Jetty bug
-
我在代码中做了一个随机的头sla傻事
相关代码如下:
CLIENT
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 handler)
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
任何人都可以想到为什么我会将请求作为空字符串随机获取?
谢谢!
EDIT
我介绍了一些更多的trace和getContentLength()在发生错误时返回-1,但是客户端输出仍然显示它正在发送正确数量的字节 .
2 回答
我想不出你为什么得到一个空字符串 . 代码看起来正确 . 如果您更新代码以检查空字符串,并且如果找到则报告请求的内容长度和传输编码,这将有助于识别罪魁祸首 . wirehark网络数据的痕迹也会很好 .
但最糟糕的是,码头-6真的已经结束,我们不太可能更新它 . 如果你今天正在编写代码,那么你真的应该使用jetty-7或8.如果你是勇敢的话,甚至可以使用jetty-9里程碑版本 . 如果你在jetty-9中发现了这样的错误,那我就像是试图为你解决它的皮疹一样!
确保设置
connection.setRequestProperty("Content-Type", "application/xml");
可能丢弃POST数据而没有某些Content-type . 当我在本地复制您的问题(针对Grails嵌入式Tomcat实例)并提供此修复它时就是这种情况 .