I have a need to parse a JSON string containing Objects, but there can also be Arrays in the JSON, which I don't need, and it's currently crashing with:
com.google.gson.JsonSyntaxException:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY
If I remove all the Arrays from the JSON, it works perfectly fine to parse the JSON with my POJO using the following code:
Type type = new TypeToken<Map<String, UsersPOJO>>(){}.getType();
Map<String, UsersPOJO> myUsers = gson.fromJson(JSONString, type);
But I'm having no luck parsing whenever there's Arrays in the JSON. I don't need, nor do I want to parse the Arrays, but if it's necessary, parsing the Arrays and then discarding the result would be okay.
How do I accomplish this with Gson? Or any other Java JSON library for that matter. Gson isn't a requirment.
This is an example of the JSON I'd be parsing:
{
"1002001":{
"level":2,
"name":"CaptKrunch",
"uid":1002001,
"user":{
"age":21,
"city":"None",
"country":"United States",
"creation":1269969663
},
"meta":{
"score":1762,
"rank":78
}
},
"1003001":{
"level":11,
"name":"LtRaine",
"uid":1003001,
"user":{
"age":35,
"city":"LA",
"country":"United States",
"creation":1269369663
},
"meta":{
"score":11562,
"rank":11
}
},
"tags_1002001": [
"conqurer",
"almighty"
]
}
You can skip array, if parse JSON string to JsonElement and iterate all elements:
Gson gson = new Gson();
//Type type = new TypeToken<Map<String, UsersPOJO>>(){}.getType();
//Map<String, UsersPOJO> myUsers = gson.fromJson(jsonString, type);
JsonParser parser = new JsonParser();
JsonElement topElement = parser.parse(jsonString);
Map<String, UsersPOJO> myUsers = new HashMap<>();
for (Map.Entry<String, JsonElement> entry : topElement.getAsJsonObject().entrySet()) {
if (entry.getValue().isJsonArray()) {
//skip or process array
} else {
myUsers.put(entry.getKey(), gson.fromJson(entry.getValue(), UsersPOJO.class));
}
}
Related
This is my input JSON From which I have to fetch interLockingGrids and store it into ArrayList<ClassType>. I have searched enough already but didn't find exactly what I want. Is there is any simplest way?
{"entity":"MasterGrid",
"data" :"{\"name\":\"MA_Pune\",
\"coordinates\" : [
{\"lat\":18.553449789265677,\"lng\":73.77419574114515},{\"lat\":18.554232972087224,\"lng\":73.77367002817823},{\"lat\":18.556135000463573,\"lng\":73.77144913093571},{\"lat\":18.555148376025496,\"lng\":73.7700973257704},{\"lat\":18.55309341985624,\"lng\":73.77075145899971},{\"lat\":18.5530421437421,\"lng\":73.77312207276918} ] ,
\"interLockingGrids\": [
{\"name\":\"Test1\",\"type\":\"CLUSTER\",\"coordinates\":[{\"lat\":18.555151666563823,\"lng\":73.7700902617189},{\"lat\":18.556135000463573,\"lng\":73.77144913093571},{\"lat\":18.556135000463573,\"lng\":73.77144913093571},{\"lat\":18.556135000463573,\"lng\":73.77144913093571},{\"lat\":18.556135000463573,\"lng\":73.77144913093571},{\"lat\":18.556135000463573,\"lng\":73.77144913093571}],\"isActive\":true,\"colorCode\":\"#D0983C\"} ,
{\"name\":\"Test2\",\"type\":\"CLUSTER\",\"coordinates\":[{\"lat\":18.5530421437421,\"lng\":73.77312207276918},{\"lat\":18.553449789265677,\"lng\":73.77419574114515},{\"lat\":18.55238201763598,\"lng\":73.7743998478852}],\"isActive\":true,\"colorCode\":\"#8E75B7\"} ] ,
"operation":"GRID_OPERATION",
"description":"Baner_Test",
"submittedBy":"m#abc.com",
"submittedById":4,
"submittedByType":"OPS" }
In a recent project I did something similar:
public List<MyType> parseJsonToListOfMyType(String json) {
Gson gson = new Gson();
JsonArray job = gson.fromJson(json, JsonArray.class);
Type listType = new TypeToken<List<MyType>>(){}.getType();
return gson.fromJson(job, listType);
}
I'm getting a JSON response (list of items) from a .NET WS, so that I want to transform to a List in my Android app. But when using GSON library, I get the following exception:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
JSON response:
{
"d": [
{
"Id":1,
"Name":"Name1",
"Email":"name1#gmail.com"
},
{
"Id":2,
"Name":"Name2",
"Email":"name2#gmail.com"
}
]
}
Android GSON code:
Gson gson = new Gson();
Type listType = new TypeToken<List<User>>(){}.getType();
List<User> users = (List<User>) gson.fromJson(response, listType);
As far as I understand, JSON is returning a list of items, and I'm also trying to parse to a list of items, so I don't understand the problem.
Thanks in advance
Your JSON is { ... }, so not a list, but d is a list.
This is completely untested, but you should do something like this:
class Foo {
List<User> d;
}
Gson gson = new Gson();
Foo foo = gson.fromJson(response, Foo.class);
List<User> users = foo.d;
I hope someone can show me where i'm doing it wrong...
I'm using sendgrid for my email tracking and it is posting a JSON like the following:
[
{
"email": "john.doe#sendgrid.com",
"timestamp": 1337966815,
"event": "click",
"url": "http://sendgrid.com"
"userid": "1123",
"template": "welcome"
}
]
Now i want to get the value of for example for "timestamp" which is 1337966815 . I've tried the following:
StringBuffer jb = new StringBuffer();
String line = null;
try {
BufferedReader reader = req.getReader();
while ((line = reader.readLine()) != null)
jb.append(line);
} catch (Exception e) { /*report an error*/ }
String jsonString = jb.toString();
Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class);
String timeStam = jsonObject.get(timestamp).toString();
The string of jsonString gives me the following which i think is in the right format:
[ { "email": "john.doe#sendgrid.com", "timestamp": 1337966815, "event": "click", "url": "http://sendgrid.com" "userid": "1123", "template": "welcome" }]
But i'm getting the following error at this line of code - JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class);
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 52
What am I doing wrong? Is it the format of jsonString that is confusing the JsonObject?
Any help would be very much appreciated.
Kind regards
Francois
The JSON you show in both examples is invalid. There is a comma missing after "url":"http://sendgrid.com"
Ignoring that, the JSON you show is an array of JSON objects, not an object. This is what the [] denotes (correcting the missing comma):
[
{
"email": "john.doe#sendgrid.com",
"timestamp": 1337966815,
"event": "click",
"url": "http://sendgrid.com",
"userid": "1123",
"template": "welcome"
}
]
If you are not mapping this JSON to a Java POJO, then you would want to use Gson's JsonParser to parse your String to a JsonElement (Note you could even use it to parse directly from the Stream, but this if for how you have your code now).
JsonElement je = new JsonParser().parse(jsonString);
Now you have what's called a "parse tree". This JsonElement is the root. To access it as an array you're going to do:
JsonArray myArray = je.getAsJsonArray();
You only show this array containing one object, but let's say it could have more than one. By iterating through the array you can do:
for (JsonElement e : myArray)
{
// Access the element as a JsonObject
JsonObject jo = e.getAsJsonObject();
// Get the `timestamp` element from the object
// since it's a number, we get it as a JsonPrimitive
JsonPrimitive tsPrimitive = jo.getAsJsonPrimitive("timestamp");
// get the primitive as a Java long
long timestamp = tsPrimitive.getAsLong();
System.out.println("Timestamp: " + timestamp);
}
Realize that Gson primarily is meant for Object Relational Mapping where you want to take that JSON and have it converted to a Java object. This is actually a lot simpler:
public class ResponseObject {
public String email;
public long timestamp;
public String event;
public String url;
public String userid;
public String template;
}
Because you have array of these, you want to use a TypeToken and Type to indicate your JSON is a List of these ResponseObject objects:
Type myListType = new TypeToken<List<ResponseObject>>(){}.getType();
List<ResponseObject> myList = new Gson().fromJson(jsonString, myListType);
I'm just starting off with json parsing and writing, and am using gson to do so.
Let's say I want to access something towards the bottom of the file, do you have to iterate through each line in the json file to get to that line?
How do you jump to Alice without having to iterate through everything Bob has? Right now I only know how to use beginObject(), beginArray() to open Bob, go through them, then close Bob, then reach Alice.
e.g.
{
"Bob": {
"following": [
215876567,
64044676,
276716878,
208675951,
151503222,
],
"followers": [
720567433,
1005407395,
2432297370,
2463742694,
2463741222,
51101660,
2463700218,
2463741192,
405107240,
]
},
"Alice": {
"location": "New York"
}
}
You can get direct Alice as below
JsonParserjsonParser = new JsonParser();
JsonElement jsonElement = jsonParser.parse(YOUR_JSON_STRING_HERE);
// get JsonElement for Alice as like this
JsonElement aliceJsonElement = jsonElement.getAsJsonObject().get("Alice");
It will give you this json object {"location":"New York"}
Finally you can parse it as
Gson gson = new Gson();
Type mapType = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> map = gson.fromJson(aliceJsonElement, mapType);
// iterate map
Like this you can get Bob AND following
jsonElement.getAsJsonObject().get("Bob")
jsonElement.getAsJsonObject().get("Bob").getAsJsonObject().get("following")
I'am struggling with a problem to parse a JSON with GSON which contains lists as values. This should be pretty simple, but I can't figure out how to solve it. The JSON is:
{
"key1": [
"foo1",
"foo2",
"foo3"
],
"key2": [
"foo4",
"foo5",
"foo6"
],
"key3": [
"foo7",
"foo8",
"foo9"
]
}
I think the best way is to put it into a Map<String, List<String>>, but I can't create a Type for it. Like:
Type jsonArrayType = new TypeToken<Map<String, List<String>>>(){}.getType();
// Doesn't work, causes exception: "com.google.gson.internal.LinkedTreeMap cannot be cast to java.util.List"
Thanks for any help!
You will get a java.lang.reflect.Type from the getType() method. Use that to parse your json. Here is a small working example (Java 7)
String json = "{\"key1\": [\"foo1\",\"foo2\",\"foo3\"],\"key2\": [\"foo4\",\"foo5\",\"foo6\"],\"key3\": [\"foo7\",\"foo8\",\"foo9\"]}";
java.lang.reflect.Type type = new TypeToken<Map<String, List<String>>>(){}.getType();
Map<String, List<String>> map = new Gson().fromJson(json, type);
System.out.println(map);
This snippet prints the below value
{key1=[foo1, foo2, foo3], key2=[foo4, foo5, foo6], key3=[foo7, foo8, foo9]}