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



我配置了apachehttpClient,如下所示:

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请求。这些字符在日志中显示为胡言乱语,但我认为这是因为DDMS不支持UTF-8,正如本期所述。

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

我还尝试在一个字段中放入250个非ascii字符,因为该特定字段最多可以容纳250个字符。然而,它无法在服务器端进行验证,服务器端声称已经超过了250个字符的限制。250个ASCII字符可以正常工作。

服务器哑弹声称他们支持UTF-8。他们甚至尝试模拟一个包含中文字符的帖子请求,服务器接收到的数据很好。然而,这家伙(一个中国人)正在使用一台安装了中文软件包的Windows电脑(我想,因为他可以在键盘上键入汉字)。

我猜安卓客户端和服务器(由中国人btw制造)使用的字符集没有对齐。但我不知道是哪一个出了问题,因为服务器哑弹声称他们支持UTF-8,而我们的rest客户端被配置为支持UTF-8。

这让我想知道Android在所有文本输入中默认使用什么字符集,以及是否可以通过程序将其更改为不同的字符集。我试图找到关于如何在输入小部件上做到这一点的资源,但没有发现任何有用的东西。

有没有一种方法可以为Android中的所有输入小部件设置字符集?或者我在rest客户端配置中遗漏了什么?或者,也许,只是也许,服务器的家伙们在他们的服务器上没有使用UTF-8,而是使用了Windows字符集?

显然,我忘记将StringEntity的字符集设置为UTF-8。这些线路成功了:

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

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

  1. rest客户端本身
  2. StringEntity

更新:正如Samuel在评论中指出的,现代的方法是使用ContentType,比如

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

我知道这篇文章有点旧,但这里有一个解决方案:

以下是我将UTF-8字符串(不管它们是xmlsoap还是json)发布到服务器的代码。我用cyrillic、hash值和其他一些特殊字符尝试了一下,它的效果很有魅力。这是我通过论坛找到的许多解决方案的汇编。

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();

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

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

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

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

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

最新更新