Кодировка Android по умолчанию при отправке http post / put - Проблемы со спецсимволами - PullRequest
18 голосов
/ 03 июня 2011

Я настроил apache httpClient следующим образом:

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

Я также включаю заголовок http "Content-Type: application / json; charset = UTF-8" для всех запросов http post и put.

Я пытаюсь отправить запросы http post / put с телом json, содержащим специальные символы (т. Е. Китайские символы с помощью клавиатуры Google Pinyin, символы и т. Д.).думаю, это потому, что DDMS не поддерживает UTF-8, как описано в этой проблеме.

Проблема в том, что когда сервер получает запрос, он иногда вообще не видит символы(особенно китайские иероглифы), или это становится бессмысленным мусором, когда мы получаем его через запрос GET.

Я также попытался поместить 250 не-ascii символов в одно поле, потому что это конкретное поле должно быть в состоянии занятьдо 250 символов.Тем не менее, он не может проверить на стороне сервера, который утверждает, что ограничение в 250 символов было превышено.250 символов ASCII работают просто отлично.

Парни из сервера утверждают, что поддерживают UTF-8.Они даже пытались смоделировать почтовый запрос, содержащий китайские символы, и данные были получены сервером просто отлично.Однако этот парень (китаец) использует компьютер под управлением Windows с установленным языковым пакетом для китайского языка (я думаю, потому что он может печатать китайские иероглифы на клавиатуре).

Я предполагаю, что используются кодировкипо клиенту Android и серверу (сделанному китайскими парнями кстати) не выровнены.Но я не знаю, кто виноват, так как серверные парни утверждают, что они поддерживают UTF-8, а наш остальной клиент настроен на поддержку UTF-8.

Это заставило меня задуматься о том, какую кодировку Android использует дляпо умолчанию для всего ввода текста, и если он может быть изменен на другой программно.Я пытался найти ресурсы о том, как сделать это для входных виджетов, но я не нашел ничего полезного.

Есть ли способ установить кодировку для всех входных виджетов в Android?Или, может быть, я что-то упустил в конфигурации остальных клиентов?Или, может быть, просто может быть, серверные парни не используют UTF-8 на своих серверах, а вместо этого использовали Windows charsets?

Ответы [ 4 ]

48 голосов
/ 03 июня 2011

Очевидно, я забыл установить кодировку StringEntity в UTF-8. Эти строки сделали свое дело:

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

Таким образом, при отправке сообщения http с символами, отличными от ascii, существует не менее двух уровней для установки кодировки в клиенте Android.

  1. Остальной клиент сам по себе
  2. StringEntity

ОБНОВЛЕНИЕ: Как отметил Самуэль в комментариях, современный способ сделать это - использовать ContentType, например, так:

    final StringEntity se = new StringEntity(body, ContentType.APPLICATION_JSON);
    httpPut.setEntity(se);
13 голосов
/ 08 ноября 2011

Я знаю, что этот пост немного устарел, но, тем не менее, вот решение:

Вот мой код для отправки строк UTF-8 (не имеет значения, xml мыло или 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();

Я надеюсь, что кто-то найдет этот код полезным. :)

5 голосов
/ 03 июня 2014

Вы должны установить кодировку вашей строковой сущности в UTF-8:

StringEntity stringEntity = new StringEntity(urlParameters, HTTP.UTF_8);
2 голосов
/ 03 июня 2011

Вы можете устранить проблему с сервером, используя curl для отправки тех же данных. Если он работает с curl, используйте --trace для проверки вывода.

Убедитесь, что вы отправляете тело контента в байтах. Сравните запрос HTTP от Android с выводом успешного запроса curl.

...