我想通过HTTP post从我的Android Mobile应用程序向服务器发送XML消息。
我尝试使用HttpUrlConnection,遵循以下步骤:
URL url = new URL(vURL);
HttpUrlConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
// Adding headers (code removed)
conn.setRequestProperty("Content-Type", "text/xml; charset=utf-16");
OutputStream out = new BufferedOutputStream(conn.getOutputStream());
// Adding XML message to the connection output stream
// I have removed exception handling to improve readability for posting it here
out.write(pReq.getBytes()); // here pReq is the XML message in String
out.close();
conn.connect();
获得响应后,流读取部分就是以这种方式完成的:
BufferedReader in = null;
StringBuffer sb;
String result = null;
try {
InputStreamReader isr = new InputStreamReader(is);
// Just in case, I've also tried:
// new InputStreamReader(is, "UTF-16");
// new InputStreamReader(is, "UTF-16LE");
// new InputStreamReader(is, "UTF-16BE");
// new InputStreamReader(is, "UTF-8");
in = new BufferedReader(isr);
sb = new StringBuffer("");
String line = "";
while ((line = in.readLine()) != null)
sb.append(line);
in.close();
result = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
现在我得到的结果字符串是一些不可读的格式/编码。
当我使用HttpClient尝试相同的操作时,它可以正常工作。一旦我在HttpClient.execute调用之后获得HttpResponse,这是流式读取部分:
BufferedReader in = null;
InputStream is;
StringBuffer sb;
String decompbuff = null;
try {
is = pResponse.getEntity().getContent();
InputStreamReader isr = new InputStreamReader(is);
in = new BufferedReader(isr);
// Prepare the String buffer
sb = new StringBuffer("");
String line = "";
while ((line = in.readLine()) != null)
sb.append(line);
in.close();
// gZip decompression of response. Note: message was compressed before
// posting it via HttpClient (Posting code is not mentioned here)
decompbuff = Decompress(sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
return decompbuff;
在理解问题时,我们对一些帮助表示赞赏。
答案 0 :(得分:1)
一个(严重)问题可能是您忽略了输入和输出的编码。
<强>输入强>
conn.setRequestProperty("Content-Type", "text/xml; charset=utf-16");
OutputStream out = new BufferedOutputStream(conn.getOutputStream());
// Adding XML message to the connection output stream
// I have removed exception handling to improve readability for posting it here
out.write(pReq.getBytes()); // <-- you use standard platform encoding
out.close();
更好:
out.write(pReq.getBytes("UTF-16"));
<强>输出强>
您可能忽略了压缩,最好看起来像这样(取自DavidWebb):
static InputStream wrapStream(String contentEncoding, InputStream inputStream)
throws IOException {
if (contentEncoding == null || "identity".equalsIgnoreCase(contentEncoding)) {
return inputStream;
}
if ("gzip".equalsIgnoreCase(contentEncoding)) {
return new GZIPInputStream(inputStream);
}
if ("deflate".equalsIgnoreCase(contentEncoding)) {
return new InflaterInputStream(inputStream, new Inflater(false), 512);
}
throw new RuntimeException("unsupported content-encoding: " + contentEncoding);
}
// ...
InputStream is = wrapStream(conn.getContentEncoding(), is);
InputStreamReader isr = new InputStreamReader(is, "UTF-16");
in = new BufferedReader(isr);
sb = new StringBuffer("");
String line = "";
while ((line = in.readLine()) != null)
sb.append(line); // <-- you're swallowing linefeeds!
in.close();
result = sb.toString();
最好让XML-Parser直接使用您的InputStream。不要创建JAVA字符串,而是让解析器扫描字节。它会自动检测XML的编码。
通常可能仍存在问题,因为我们不知道您使用的是什么类型的UTF-16。可以是BigEndian或LittleEndian。这就是为什么我问,如果你真的需要UTF-16。如果您不需要使用某些亚洲语言,UTF-8应该更高效,更易于使用。
所以我给你的“解决方案”不能保证工作 - 你必须摆弄UTF-16 BE / LE,祝你好运和耐心。
另一个评论:在上面的示例中,您首先构造String,然后Decompress
。这是错误的顺序。流被压缩(gzip,deflate)并且必须首先解压缩。然后你得到String。