Подтвердить что ты не робот

Android-кодировка Android по умолчанию при отправке http post/put - Проблемы со специальными символами

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

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

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

  • Сам клиент-клиент
  • StringEntity

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

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

Ответ 2

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

Вот мой код для публикации строк 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();

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

Ответ 3

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

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

Ответ 4

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

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