web-dev-qa-db-ja.com

Android http post / put送信時のデフォルトの文字セット-特殊文字の問題

ApachehttpClientを次のように構成しました。

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

また、すべてのhttppostおよびputリクエストにhttpヘッダー「Content-Type:application/json; charset = UTF-8」を含めます。

特殊文字(Googleピンインキーボードを介した漢字、記号など)を含むjson本文を使用してhttp post/putリクエストを送信しようとしていますが、ログに文字がぎこちなく表示されますが、これはDDMSが行うためだと思います this の問題で説明されているように、UTF-8をサポートしていません。

問題は、サーバーがリクエストを受信したとき、文字(特に漢字)がまったく表示されないこと、またはGETリクエストを介して取得したときに意味のないゴミになることです。

また、特定のフィールドは最大250文字を使用できるはずなので、1つのフィールドに250文字のASCII以外の文字を入れてみました。ただし、250文字の制限を超えたと主張するサーバー側では検証に失敗します。 250 ASCII文字は問題なく機能します。

サーバーの男は、UTF-8をサポートしていると主張しています。彼らは漢字を含むPOSTリクエストをシミュレートしようとしましたが、データはサーバーによって問題なく受信されました。しかし、その男(中国人の男)は、中国語の言語パックがインストールされたWindowsコンピューターを使用しています(キーボードで漢字を入力できるためだと思います)。

Androidクライアントとサーバー(中国人によって作成された)によって使用されている文字セットが整列していないと推測していますが、サーバーが原因でどちらに問題があるのか​​わかりませんそれらがUTF-8をサポートしていると主張し、残りのクライアントはUTF-8をサポートするように構成されています。

これにより、すべてのテキスト入力でcharset Androidがデフォルトで使用するもの、およびプログラムで別の文字セットに変更できるかどうか)について疑問に思いました。入力ウィジェットでこれを行う方法に関するリソースを見つけようとしました。しかし、私は何も役に立ちませんでした。

Androidのすべての入力ウィジェットに文字セットを設定する方法はありますか?それとも、残りのクライアント構成で何かを見逃したのでしょうか?あるいは、たぶん、サーバーの男はサーバーでUTF-8を使用しておらず、代わりにWindows文字セットを使用しているのでしょうか。

18
avendael

どうやら、StringEntityの文字セットをUTF-8に設定するのを忘れていたようです。これらの行はトリックをしました:

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

したがって、ASCII以外の文字を含むhttp投稿を送信する場合、Androidクライアントで文字セットを設定するには、少なくとも2つのレベルがあります。

  1. 残りのクライアント自体
  2. StringEntity

更新:サミュエルがコメントで指摘したように、それを行うための現代的な方法は、次のようにContentTypeを使用することです。

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

私はこの投稿が少し古いことを知っていますが、それでもここに解決策があります:

これは、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();

誰かがこのコードがお役に立てば幸いです。 :)

文字列エンティティの文字セットをUTF-8に設定する必要があります。

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

curlを使用して同じデータを送信することにより、問題としてのサーバーを排除できます。 curlで機能する場合は、--traceを使用して出力を確認します。

コンテンツ本文をバイトとして送信していることを確認してください。 AndroidからのHTTPリクエストを、成功したcurlリクエストからの出力と比較します。

2
Mullins