I've recently started playing around with JSON
strings, and was told that Google's own library, Gson
, is the new and hip way of dealing with these.
The way I've understood it, is that a JSON
string is essentially a map. Where each variable points to a value in the string.
For example:
String jsonInput2 = "{\"created_at\":\"Sat Feb 08 15:37:37 +0000 2014\",\"id\":432176397474623489\"}
Thus far, all is well. Information such as when this JSON
string was created, can be assigned to a variable with the following code:
Gson gson = new Gson();
Map<String, String> map = new HashMap<String, String>();
map = (Map<String, String>) gson.fromJson(jsonInput, map.getClass());
String createdAt = map.get("created_at");
It's almost artistic in in simple beauty. But this is where the beauty ends and my confusion begins.
The following is an extension of the above JSON
string;
String jsonInput2 = "{\"created_at\":\"Sat Feb 08 15:37:37 +0000 2014\",\"id\":432176397474623489\",\"user\":{\"id_str\":\"366301747\",\"name\":\"somethingClever\",\"screen_name\":\"somethingCoolAndClever\"}}";
My question is how these "brackets within brackets" work for the user
section of the JSON
?
How could I assign the values specified within these inner-brackets to variables?
Can anyone explain to me, or show me in code, how Gson
handles stuff like this, and how I can use it?
In short, why does...
String jsonInput = "{\"created_at\":\"Sat Feb 08 15:37:37 +0000 2014\",\"id\":432176397474623489\",\"user\":{\"id_str\":\"366301747\",\"name\":\"somethingClever\",\"screen_name\":\"somethingCoolAndClever\"}}";
Gson gson = new Gson();
Map<String, String> map = new HashMap<String, String>();
map = (Map<String, String>) gson.fromJson(jsonInput, map.getClass());
String name = map.get("name");
System.out.println(name);
... print out null
?
user
is aJsonObject
itself:Forget about Java. You need to first understand the JSON format.
This is basically it
Your second JSON
String
(which has a missing"
) is the following (use jsonlint.com to format)The JSON is an object, outer
{}
, that contains three pairs,created_at
which is a JSON string,id
which is also a JSON string, anduser
which is a JSON object. That JSON object contains three more pairs which are all JSON strings.You asked
Most advanced JSON parsing/generating libraries are meant to convert JSON to Pojos and back.
So you could map your JSON format to Java classes.
Note the
@SerializedName
so that you can keep using Java naming conventions for your fields.You can now deserialize your JSON
would print
showing that all the fields were set correctly.
The source code of Gson is freely available. You can find it online. It is complex and a source code explanation wouldn't fit here. Simply put, it uses the
Class
object you provide to determine how it will map the JSON pairs. It looks at the corresponding class's fields. If those fields are other classes, then it recurs until it has constructed a map of everything it needs to deserialize.Because your root JSON object, doesn't have a pair with name
name
. Instead of usingMap
, use Gson'sJsonObject
type.which prints
The above method class could have thrown a number of exceptions if they weren't the right type. If, for example, we had done
it would fail because
user
is not a JSON array. Specifically, it would throwSo the
JsonElement
class (which is the parent class ofJsonObject
,JsonArray
, and a few others) provides methods to check what it is. See the javadoc.For people that come here searching for a way to convert LinkedTreeMap to object:
This was usefull for me when i needed to parse an generic object like:
But i don't know which object the server was going to send. The objectFull will become a LinkedTreeMap
Ok. First of all JSON is short for "JavaScript Object Notation" so your assertion that "a JSON string is essentially a map" is incorrect. A JSON block is an object graph, described using the JavaScript language syntax. Since your trying to coerce an object graph to a Map of String, Sting kay value pairs, this is only going to work in cases where any given JSON object graph is essentially just that (so not very often). A more successful strategy would probably be
gson.fromJson()
which will convert your JSON to a proper Java object graph.The JSON string has following structure:
When you put the values in the map using the code:
It has following key values:
and that's why you are able to use
map.get("created_at")
.Now, since you want to get the name of the user, you need to get the map of user:
In the
userMap
, you would get following key values:Now, you can get the
name
of theuser