简体   繁体   English

Android:将String转换为JSONObject时出现异常

[英]Android: Exception when converting a String into a JSONObject

I get the following Error when I try to convert a JSON String into a JSONObject. 当我尝试将JSON字符串转换为JSONObject时,我收到以下错误。

Value 48.466667|9.883333 at location of type java.lang.String cannot be converted to JSONObject 在类型java.lang.String的位置的值48.466667 | 9.883333无法转换为JSONObject

The String is valid JSON, I tested it with http://jsonlint.com/ String是有效的JSON,我用http://jsonlint.com/测试了它

Example: {"name":"An der Decke","location":" 48.412583|10.0385 ","type":"Virtual","size":null,"status":"Available","difficulty":1,"rating":null,"terrain":1} 示例:{“name”:“An der Decke”,“location”:“ 48.412583 | 10.0385 ”,“type”:“Virtual”,“size”:null,“status”:“Available”,“difficulty”:1 , “等级”:空, “地形”:1}

The code that produces the exception looks like that: 产生异常的代码如下所示:

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!
    }
}

Is the pipe | 是管道 symbol not a valid character in Java JSON? 符号不是Java JSON中的有效字符?

EDIT: 编辑:

The thing is, it works fine if the JSON String doesn't include the "location":"48.412583|10.0385" part... 问题是,如果JSON字符串不包含“位置” ,它可以正常工作:“48.412583 | 10.0385”部分......

You seem to misunderstand how the org.json library works. 您似乎误解了org.json库的工作原理。

As explained on the JSON homepage , a JSON value can be a string, number, object, array, true/false or null. JSON主页中所述 ,JSON值可以是字符串,数字,对象,数组,true / false或null。 The library maps these value types to String , Number subclasses, JSONArray , JSONObject , Boolean or null . 库将这些值类型映射到StringNumber子类, JSONArrayJSONObjectBooleannull

Not everything in that library is a JSONObject . 并非该库中的所有内容都是JSONObject In fact, a JSONObject is specifically used to represent a name/value pair object. 实际上, JSONObject 专门用于表示名称/值对对象。 JSONObject.get() can potentially return any of the aforementioned value types, that's why it needs to fall back to the greatest common denominator type: Object (and not JSONObject ). JSONObject.get()可能会返回任何上述值类型,这就是为什么它需要回退到最大的公分母类型: Object (而不是 JSONObject )。 Thus, casting everything to a JSONObject won't work. 因此,将所有内容转换为JSONObject将不起作用。

It's your responsibility to ensure that you're casting to the correct type using your knowledge of the incoming data structure. 您有责任使用您对传入数据结构的了解,确保您使用正确的类型。 This seems to be a problem in your case: your JSON string contains strings (for name , location , type and status ), integers (for difficulty and terrain ) and nulls (for size ). 在您的情况下,这似乎是一个问题:您的JSON字符串包含字符串(用于namelocationtypestatus ),整数(用于difficultyterrain )和空值(用于size )。 What exactly are you trying to do with these? 究竟想用这些做什么?

The get() method of JSONObject returns a result of type Object . JSONObjectget()方法返回Object类型的结果。 In this case, it seems it is a String . 在这种情况下,它似乎是一个String It's as if you were doing 这就好像你在做

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

which obviously makes no sense as they are incompatible types. 这显然没有意义,因为它们是不兼容的类型。

Instead, retrieve the value, create a JSONObject from it and add it to the JSONArray . 相反,检索值,从中创建一个JSONObject并将其添加到JSONArray

If your goal is just to get a JSONArray of all your JSON string values, there's a much simpler way to do it. 如果您的目标只是获取所有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]

With that aside, you were wrong to assume that every value encapsulated within JSON would be a JSON object itself. 除此之外,您错误地认为JSON中封装的每个值都是JSON对象本身。 In fact, in your case none of them are. 事实上,在你的情况下,没有一个是。 The correct types of all the values in your JSON are 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

On the other hand, if your name was an embedded JSON object consisting of first, middle and last names, your JSON string (ignoring the rest of the keys for brevity) would have looked like 另一方面,如果您的name是由名字,姓名和姓氏组成的嵌入式JSON对象,那么您的JSON字符串(为了简洁而忽略其余的键)看起来像

{"name": {"fname" : "An", "mname" : "der", "lname" : "Decke"}}

Now, we can put getJSONObject() to use because we really do have an embedded JSON object. 现在,我们可以使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM