发送http post / put时Android默认字符集 - 特殊字符问题

时间:2011-06-03 13:31:43

标签: android http character-encoding special-characters cjk

我已经像这样配置了apache httpClient:

HttpProtocolParams.setContentCharset(httpParameters, "UTF-8");
HttpProtocolParams.setHttpElementCharset(httpParameters, "UTF-8");

我还为所有http post和put请求包含http标题“Content-Type:application / json; charset = UTF-8”。

我正在尝试使用包含特殊字符的json正文发送http post / put请求(即通过Google拼音键盘输入中文字符,符号等)字符在日志中显示为乱码,但我认为这是因为DDMS不支持UTF-8,如this问题所述。

问题是当服务器收到请求时,它有时根本看不到字符(尤其是中文字符),或者当我们通过GET请求检索它时它变成无意义的垃圾。

我还尝试在一个字段中放置250个非ascii字符,因为该特定字段最多可以包含250个字符。但是,它无法在服务器端验证声称已超过250个字符限制。 250个ASCII字符可以正常工作。

服务器家伙声称他们支持UTF-8。他们甚至尝试模拟包含中文字符的发布请求,并且服务器接收到的数据就好了。然而,这个家伙(一个中国人)正在使用装有中文语言包的Windows电脑(我想,因为他可以在键盘上输入中文字符)。

我猜测Android客户端和服务器(由中国人btw制作)使用的字符集不对齐。但我不知道哪一个有问题,因为服务器家伙声称他们支持UTF-8,而我们的rest客户端配置为支持UTF-8。

这让我想知道Android在默认情况下在所有文本输入上使用什么字符集,以及是否可以以编程方式将其更改为其他字符串。我试图找到有关如何在输入小部件上执行此操作的资源,但我没有找到任何有用的东西。

有没有办法为Android中的所有输入小部件设置charset?或者我可能错过了其他客户端配置中的某些内容?或许,也许,只是可能,服务器家伙没有在他们的服务器上使用UTF-8而是使用Windows字符集?

4 个答案:

答案 0 :(得分:48)

显然,我忘了将StringEntity的字符集设置为UTF-8。这些线路起到了作用:

    httpPut.setEntity(new StringEntity(body, HTTP.UTF_8));
    httpPost.setEntity(new StringEntity(body, HTTP.UTF_8));

因此,在发送带有非ascii字符的http帖子时,至少有两个级别可以在Android客户端中设置字符集。

  1. 其余客户本身
  2. StringEntity
  3. 更新:正如Samuel在评论中指出的那样,现代的方法是使用ContentType,如下所示:

        final StringEntity se = new StringEntity(body, ContentType.APPLICATION_JSON);
        httpPut.setEntity(se);
    

答案 1 :(得分:13)

我知道这篇文章有点陈旧但不过这是一个解决方案:

这是我向服务器发布UTF-8字符串(如果它们是xml soap或json无关紧要)的代码。我用西里尔字母,哈希值和一些其他特殊字符尝试了它,它就像一个魅力。它是我通过论坛找到的许多解决方案的汇编。

HttpParams httpParameters = new BasicHttpParams();
HttpProtocolParams.setContentCharset(httpParameters, HTTP.UTF_8);
HttpProtocolParams.setHttpElementCharset(httpParameters, HTTP.UTF_8);

HttpClient client = new DefaultHttpClient(httpParameters);
client.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_1);
client.getParams().setParameter("http.socket.timeout", new Integer(2000));
client.getParams().setParameter("http.protocol.content-charset", HTTP.UTF_8);
httpParameters.setBooleanParameter("http.protocol.expect-continue", false);
HttpPost request = new HttpPost("http://www.server.com/some_script.php?sid=" + String.valueOf(Math.random()));
request.getParams().setParameter("http.socket.timeout", new Integer(5000));

List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
// you get this later in php with $_POST['value_name']
postParameters.add(new BasicNameValuePair("value_name", "value_val"));

UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters, HTTP.UTF_8);
request.setEntity(formEntity);
HttpResponse response = client.execute(request);

in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String lineSeparator = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
    sb.append(line);
    sb.append(lineSeparator);
}
in.close();
String result = sb.toString();

我希望有人会发现这段代码很有帮助。 :)

答案 2 :(得分:5)

您应该将字符串实体的字符集设置为UTF-8:

StringEntity stringEntity = new StringEntity(urlParameters, HTTP.UTF_8);

答案 3 :(得分:2)

您可以使用curl发送相同数据来消除服务器问题。 如果它与curl一起使用--trace来检查输出。

确保以字节形式发送内容正文。将来自Android的HTTP请求与成功curl请求的输出进行比较。