これがすでに回答されているかどうかはわかりませんが、クイック検索では満足のいく結果が得られませんでした..
次のシナリオで立ち往生しています:
- REST API と JSON 形式のデータ BLOB を使用する Web サービス
- このサービスと通信し、ローカルでデータをキャッシュ/処理する Android クライアント アプリ
we サービスはドイツの会社によって運営されているため、結果データの一部の文字列にはドイツ語のウムラウトなどの特殊文字が含まれています。
// example resonse
[
{
"title" : "reward 1",
"description" : "Ein gro\u00dfer Kaffee f\u00fcr dich!"
},
{
"title" : "reward 2",
"description" : "Eine Pizza f\u00fcr dich!"
},
...
]
アプリはローカルで、応答オブジェクトを反映する一連のクラスを使用してデータを解析しています (例:上の例のRewardクラスとRewardResponseクラス)。これらの各クラスは、JSON から / への読み取りとダンプを行うことができますが、これが厄介なところです。
上記の例では、org.json はデータを正しく解析し、結果の文字列には特殊文字 'ß' ( \u00df ) と 'ü' ( \u00fc ) の適切な Unicode バージョンが含まれます。
final RewardResponse response = new RewardResponse(jsonData);
final Reward reward = response.get(0);
// this will print "Ein großer Kaffee für dich!"
Log.d("dump server data", reward.getDescription());
final Reward reward2 = new Reward(reward.toJSON());
// this will print "Ein gro�er Kaffee f�r dich!"
Log.d("dump reloaded data", reward2.getDescription());
ご覧のとおり、JSONObject.toString()によって生成されたデータのロードに問題があります。
主に何が起こっているかというと、JSONObjectは"\uXXXX"の形式でエスケープを解析しますが、プレーンな UTF-8 テキストとしてダンプします。
次に、解析時に Unicode を適切に読み取らず、代わりに結果文字列に置換文字を挿入します (コード ポイントとして\uffffの上)。
私の現在の回避策は、Unicode Latin1 補助文字とそれぞれのエスケープ バージョン ( \u00a0から\u00ffまで) を含むルックアップ テーブルで構成されています。しかし、これはまた、何かをダンプするたびに、ダンプされたすべての JSON テキストを調べて、文字をエスケープされたバージョンに置き換える必要があることも意味します。
もっといい方法があれば教えてください!
(注:この質問がありますが、彼はディスク上のローカルファイルエンコーディングに問題がありました。
ご覧のとおり、上記の私の問題は、ディスクに書き込むことなく再現可能です)
編集:コメントで要求されているように、toJSON()メソッドは次のとおりです。
public final String toJSON() {
JSONObject obj = new JSONObject();
// mTitle and mDescription contain the unmodified
// strings received from parsing.
obj.put("title", mTitle);
obj.put("description", mDescription);
return obj.toString();
}
補足として、 JSONObject.toString()またはJSONStringerを使用しても違いはありません。(ドキュメントでは.toString()の使用を推奨しています)
編集:方程式から報酬を削除するだけで、これは問題を再現します:
final JSONObject inputData = new JSONObject("{\"description\":\"Ein gro\\u00dfer Kaffee\"}");
final JSONObject parsedData = new JSONObject(inputData.toString());
Log.d("inputData", inputData.getString("description"));
Log.d("parsedData", parsedData.getString("description"));