简体   繁体   中英

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.

Value 48.466667|9.883333 at location of type java.lang.String cannot be converted to JSONObject

The String is valid JSON, I tested it with 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}

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?

EDIT:

The thing is, it works fine if the JSON String doesn't include the "location":"48.412583|10.0385" part...

You seem to misunderstand how the org.json library works.

As explained on the JSON homepage , a JSON value can be a string, number, object, array, true/false or null. The library maps these value types to String , Number subclasses, JSONArray , JSONObject , Boolean or null .

Not everything in that library is a JSONObject . In fact, a JSONObject is specifically used to represent a name/value pair object. 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 ). Thus, casting everything to a JSONObject won't work.

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 ). What exactly are you trying to do with these?

The get() method of JSONObject returns a result of type Object . In this case, it seems it is a 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 .

If your goal is just to get a JSONArray of all your JSON string values, there's a much simpler way to do it.

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. In fact, in your case none of them are. The correct types of all the values in your JSON are

// 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": {"fname" : "An", "mname" : "der", "lname" : "Decke"}}

Now, we can put getJSONObject() to use because we really do have an embedded JSON object.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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