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?
Ответы
Ответ 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
.