gpt4 book ai didi

android - Android 中 HttpUrlConnection 的编码问题

转载 作者:行者123 更新时间:2023-11-29 01:45:14 24 4
gpt4 key购买 nike

我想通过 HTTP post 从我的 Android 移动应用向服务器发送 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;

在理解问题方面提供一些帮助。

最佳答案

一个(严重的)问题可能是您忽略了输入和输出的编码。

输入

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,然后对其进行了解压缩。那是错误的顺序。流是压缩的(gzip、deflate),必须先解压。然后你得到字符串。

关于android - Android 中 HttpUrlConnection 的编码问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21876227/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com