在android上处理包含特殊字符的JSON数据的正确方法?

时间:2013-01-11 08:31:40

标签: android json encoding unicode-escapes

不确定这是否已经回答,但快速搜索没有达到令人满意的结果。
我坚持以下情况:

  • 使用REST API和JSON格式的数据blob的Web服务
  • android客户端应用程序与此服务通信并本地缓存/处理数据

我们的服务由德国公司运营,因此结果数据中的某些字符串包含特殊字符,如德语变音符号:

// example resonse
[
    {
         "title" : "reward 1",
         "description" : "Ein gro\u00dfer Kaffee f\u00fcr dich!"
    },
    {
         "title" : "reward 2",
         "description" : "Eine Pizza f\u00fcr dich!"
    },
    ...
]

本地应用程序正在使用一组镜像响应对象来解析数据(例如,上层示例的奖励 RewardResponse 类)。这些类中的每一个都可以从/向JSON读取和转储自身 - 但这是事情变得丑陋的地方。

以上示例为例,org.json将正确解析数据,结果字符串将包含特殊字符'ß'( \ u00df )和'ü'的正确Unicode版本( \ u00fc )。

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文本,并在每次转储时将字符替换为转义版本。

请告诉我有更好的方法!

(注意:有this question但他在磁盘上遇到本地文件编码问题 正如你所看到的,我上面的问题是可重复的,无需写入磁盘)

编辑:根据评论中的要求, 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"));

1 个答案:

答案 0 :(得分:0)

[注意:发布为更好格式化的答案]

我刚试过这个例子

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"));

在我运行Android 4.2.1的Nexus 7上,以及运行4.1.2的Nexus S上,它按预期工作:

D/inputData(17281): Ein großer Kaffee
D/parsedData(17281): Ein großer Kaffee

你在哪个Android版本中看到了这个问题?