Android:将字符串转换为JSONObject时出现异常

3
当我试图将JSON字符串转换为JSONObject时,我遇到了以下错误。
“在类型为java.lang.String的位置上的值<48.466667 | 9.883333>无法转换为JSONObject。”
该字符串是有效的JSON,我用http://jsonlint.com/进行了测试。
示例: {"name":"An der Decke","location":"48.412583|10.0385","type":"Virtual","size":null,"status":"Available","difficulty":1,"rating":null,"terrain":1}
产生异常的代码如下:
jsonObject = new JSONObject(result);
jsonArray = new JSONArray();
Iterator<String> iter = jsonObject.keys();
while (iter.hasNext()) {
    String key = iter.next();
    try {
        JSONObject value = (JSONObject) jsonObject.get(key);   <---- Exception
        jsonArray.put(value);
    } catch (JSONException e) {
        // Something went wrong!
    }
}

在Java JSON中,管道符号“|”是否不是有效字符?

编辑:

问题在于,如果JSON字符串不包括"location":"48.412583|10.0385"部分,它可以正常工作...

3个回答

2

你好像误解了org.json库的工作方式。

正如在JSON主页上所解释的,JSON值可以是字符串、数字、对象、数组、true/false或null。该库将这些值类型映射到StringNumber子类、JSONArrayJSONObjectBooleannull

该库中并不是所有内容都是JSONObject实际上,JSONObject专门用于表示名称/值对对象。 JSONObject.get()可能返回任何前述值类型之一,这就是为什么它需要回退到最大公共分母类型:Object(而不是JSONObject)。因此,将所有内容强制转换为JSONObject是行不通的。

你有责任使用你对传入数据结构的了解来确保你将其强制转换为正确的类型。这似乎是你的情况中存在问题的原因:你的JSON字符串包含字符串(用于namelocationtypestatus)、整数(用于difficultyterrain)和nulls(用于size)。你究竟想对这些内容做什么?


0

get() 方法返回 JSONObject 类型的结果。在这种情况下,它似乎是一个 String。就好像你正在做的一样。

JSONObject value = (JSONObject) new String("asdasdsa");

这显然是没有意义的,因为它们是不兼容的类型。

相反,检索该值,从中创建一个JSONObject并将其添加到JSONArray中。


0
如果你的目標只是為了獲取所有 JSON 字符串值的 JSONArray,那麼有一種更簡單的方法可以實現。
JSONObject jsonObject = new JSONObject(result);
JSONArray jsonArray = jsonObject.toJSONArray(jsonObject.names());

System.out.println(jsonArray); // prints:
// [1,"Available","48.412583|10.0385","An der Decke",1,null,"Virtual",null]

话虽如此,你错误地假设 JSON 中封装的每个值本身都是一个 JSON 对象。实际上,在你的情况下,它们中没有一个是。你的 JSON 中所有值的正确类型为

// String
System.out.println(jsonObject.getString("name")); // An der Decke
System.out.println(jsonObject.getString("location")); // 48.412583|10.0385
System.out.println(jsonObject.getString("type")); // Virtual
System.out.println(jsonObject.getString("status")); // Available

// Null
System.out.println(jsonObject.isNull("size")); // true
System.out.println(jsonObject.isNull("rating")); // true

// Integer
System.out.println(jsonObject.getInt("terrain")); // 1
System.out.println(jsonObject.getInt("difficulty")); // 1

另一方面,如果你的name是一个嵌入式JSON对象,由名字、中间名和姓氏组成,那么你的JSON字符串(为简洁起见,忽略其他键)将如下所示:
{"name": {"fname" : "An", "mname" : "der", "lname" : "Decke"}}

现在,我们可以使用getJSONObject(),因为我们确实有一个嵌入的JSON对象。
JSONObject jsonObj = new JSONObject("{\"name\":
                     {\"fname\" : \"An\", \"mname\" : \"der\", \"lname\" : \"Decke\"}}");

// get embedded "name" JSONObject
JSONObject name = jsonObj.getJSONObject("name");

System.out.println(name.getString("fname") + " "
                 + name.getString("mname") + " "
                 + name.getString("lname")); // An der Decke

好的,这意味着我必须根据每个项目的类型进行处理...谢谢 - user2708728
@user2708728,是的。我还添加了一个关于何时使用getJSONObject()的示例。 - Ravi K Thapliyal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接