Getting the values from a JSON string in Java using GSON - java

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);

Related

Is there a way to name each JSONObject in an array?

{
"Object1": {
"description": "An object",
"data": "more data"
},
"Object2": {
"description": "An object",
"data": "more data"
}
}
How would I use GSON to iterate over the elements in this JSON Object to easily parse each element one by one?
Yes there is, but PrabhakarP is right, associative arrays in JSON are objects. So in your case,
{
"Object1": {
"description": "An object",
"data": "more data"
}
}
You would have a meta-object containing each array element as a property, which doesn't really make sense. You should parse it differently.
But if you still need, in GSON, then try ,
JsonArray body = gson.fromJson(yourString, JsonArray.class);
JSONObject metaObj = new JSONObject();
for (JsonElement currEle : paymentsArray) {
JSONObject currObj = currEle.getAsJsonObject();
String nameVal = currObj.get("name");
currObj.remove("name");
metaObj.addProperty(nameVal, currObj);
}
I would suggest you to add a property to each object in array and use it
I looked at the man page and found I could loop over the set of members in the object.
JsonObject obj = gson.fromJson(jsonFile, JsonObject.class);
for(Map.Entry<String, JsonElement> element : obj.entrySet()) {
Object obj = gson.fromJson(element.getValue(), Object.class);
// do stuff with the object
}

json array to individual strings

Assignment: I am using json-simple. How can I convert this json data into individual java strings?
(Please forgive me if you think that this is a low-level question - I am new to JSON, so I don't know much about that - I've searched a lot, but I couldn't find any answers)
I can get the data if there is only one object ... like this ...
{
"name": "Abhi",
"age": "21"
}
But, I can't get the data if it is in the array
[{
"name": "Abhi",
"age": "21"
}, {
"name": "shek",
"age": "7"
}]
my program logic for json object
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader("A:/c/dataFile.json"));
JSONObject jObj = (JSONObject) obj;
String gName = (String) jObj.get("name");
String gAge = (String) jObj.get("age");
System.out.println(gName);
System.out.println(gAge);
Can anyone show me how to get the data? maybe a code snippet?
Thanks in advance for your answer!
Because in your second case you are getting JSONArray
you may need to check the instance of obj as
if (jObj instanceof JSONObject)
else if (jObj instanceof JSONArray)

How to override the 2nd Object JSON with 1st JSON object

I have a situation where I need to override 2nd JSON object value to 1st.
JSON original :-
{
"products": {
"productsApp15": {
"status": "active",
"attribute_set": "Apparel",
"name": "productsApp16",
"product_type": "product",
"code": "productsApp16"
}
}
}
My 1st object :-
{
"productsApp15": {
"attribute_set": "Apparel",
"status": "active",
"name": "productsApp16",
"product_type": "product",
"code": "productsApp16"
}
}
My 2nd object :-
{
"attribute_set": "Apparel",
"status": "active",
"name": "productsApp16",
"product_type": "product",
"code": "try"
}
If you see the value of key -> code is updated here. I want this change in my real or 1st JSON object so I can pass it to my Payload
My Code:-
FileReader reader = new FileReader(filePath);
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(reader);
JSONObject jsonObject1 = (JSONObject) jsonObject.get("products");
JSONObject jsonObject2 = (JSONObject)jsonObject1.get("productsApp15");
String firstName = (String) jsonObject2.get("code").toString();
System.out.println("The first name is: " + firstName);
jsonObject2.remove("code");
jsonObject2.put("code", "try");
JSONObject jsonObject3 = (JSONObject)jsonObject1.get("productsApp15");
String firstName2 = (String) jsonObject2.get("code").toString();
System.out.println("The first name is: " + jsonObject3);
JSONObject combined = new JSONObject();
combined.put("Object1", jsonObject1);
combined.put("Object2", jsonObject3);
String firstName3 = (String) jsonObject2.get("code").toString();
System.out.println("The first name is: " + combined);
My Main objective :- I am reading a file which contain my JSON, As you can see my object is again inside an another object .
I want to update the value and then want to pass it to payload.
But how to get the original JSON structure with updated value?
Is it possible?
By Constructing the Java classes against the structure that is required in JSON, this can be achieved.
Messing up with JSON with JSON readers and parser is risky.
public class Products{
private List<Product> productsList;
}
public class Product{
private Map<String, ProProps> map = new HashMap<>();
class ProProps{
private String code;
private String name;
...
}
}
This gives you to map the objects and values.
Get the value of product that you want by key and replace the required props that you want.
Though the conversion of Java - Json takes place, there can be many extensions that can happen when you develop.
You can use this example to convert and do the manipulations required.

Parsing json webservice Response with Gson (Expected BEGIN_OBJECT but was BEGIN_ARRAY)

I'm trying to parse the spotify web-service response to get an artists' tracks which is like this:
{
"info": {
"num_results": 2974,
"limit": 100,
"offset": 0,
"query": "foo",
"type": "track",
"page": 1
},
"tracks": [
{
"album": {
"released": "2009",
"href": "spotify:album:1zCNrbPpz5OLSr6mSpPdKm",
"name": "Greatest Hits",
"availability": {
"territories": "AD AR AT AU BE BG BO BR CA CH CL CO CR CY CZ DE DK DO EC EE ES FI FR GB GR GT HK HN HU IE IS IT LI LT LU LV MC MT MX MY NI NL NO NZ PA PE PH PL PT PY RO SE SG SI SK SV TR TW US UY"
}
},
"name": "Everlong",
"popularity": "0.79",
"external-ids": [
{
"type": "isrc",
"id": "USRW29600011"
}
],
"length": 249.986,
"href": "spotify:track:07q6QTQXyPRCf7GbLakRPr",
"artists": [
{
"href": "spotify:artist:7jy3rLJdDQY21OgRLCZ9sD",
"name": "Foo Fighters"
}
],
"track-number": "3"
}]
}
I am using the Gson library to do this. So far I have tried this in my java code:
JsonParser parser = new JsonParser();
JsonObject jObject = parser.parse(jsonString).getAsJsonObject();
JsonArray jArray = jObject.get("tracks") .getAsJsonArray();
Gson gson = new Gson();
List<Track> trackArr = new ArrayList<Track>();
Type collectiontype = new TypeToken<Collection<Track>>(){}.getType();
Collection<Track> trackColl = gson.fromJson(jArray.toString(), collectiontype);
But I am getting the error : com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY
I don't understand why is it expecting begin object if I am doing "getAsJsonArray()" when trying to get the "tracks" object whihc in the json string is an array [].
The list of 'Track' was when I was doing this in a loop to get all the tracks into an array:
for (JsonElement jsonElement : jArray) {
Type collectiontype = new TypeToken<Collection<Track>>(){}.getType();
Collection<Track> trackCol = gson.fromJson(jsonElement, collectiontype);
trackArr.add((Track) trackCol);
}
What am I doind wrong here ?
I appreciate any guidance.
You don`t have to use extra library to parse a JSON file. Also use this link to read your JSON file in a human readable way.
Use the Native one as the following example:
Imports:
import org.json.JSONArray;
import org.json.JSONObject;
The code of parsing will be:
JSONObject fileJSONObject = new JSONObject(response);
JSONObject infoJSONObject = fileJSONObject.getJSONObject("info");
JSONArray tracksJSONArray = fileJSONObject.getJSONArray("tracks");
//Parsing the info
String trackType = infoJSONObject.getString("type");
String trackLimit = infoJSONObject.getString("limit");
//The rest of attributes
//Parsing the track list
JSONObject object;
for(int i=0;i<tracksJSONArray.length();i++){
object = tracksJSONArray.getJSONObject(i);
String trackName = object.getString("name");
//The rest of attributes
}
I recommend for you to Create a track class that contain all the needed attributes and their setter and getter and at the end of the parsing of each track create a new track.
I hope it helps
You can use my lib for solve this problem. For example you can do it.
private static List<Object> SpotifyTest()
{
InformationHandler informationHandler = null;
Injector injector = Guice.createInjector(new Module());
informationHandler = injector.getInstance(SpotifyService.class);
informationHandler.executeWithValue("la bamba");
return informationHandler.getDataModel();
}
The solution returns a List with a lot of HashMap where each key is a enumeration of key on service, the enumarator is:
public enum SpotifyKey
{
ALBUM_RELEASED,
ALBUM_HREF,
ALBUM_NAME,
ALBUM_AVAILABILITY,
NAME,
POPULARITY,
LENGTH,
HREF,
ARTIST_HREF,
ARTIST_NAME,
TRACK_NUMBER,
ID
}
Also you can view the code on github https://github.com/WeCodeMx/WCMPopularService/tree/develop

parse json rest response in java

I am trying to parse json output from neo4j in java as:
Object obj = parser.parse(new FileReader("D:\\neo4j.json"));
JSONArray json = (JSONArray) obj;
System.out.println(json.size());
for (int i = 0; i < json.size(); i++) {
JSONObject jsonObject = (JSONObject) json.get(i);
String data = (String);
jsonObject.get("outgoing_relationships");
String name = (String) jsonObject.get("name");
System.out.println(data);
System.out.println(name);
}
Can somebody help me to get values inside "data" element:
I have json output from neo4j as follows:
[{
"outgoing_relationships": "http://host1.in:7474/db/data/node/133/relationships/out",
"data": {
"MOTHERS_NAME": "PARVEEN BAGEM",
"MOBILE_NO": "9211573758",
"GENDER": "M",
"name": "MOHD",
"TEL_NO": "0120-",
"PINCODE": "110001"
},
"traverse": "http://host1.in:7474/db/data/node/133/traverse/{returnType}",
"all_typed_relationships": "http://host1.in:7474/db/data/node/133/relationships/all/{-list|&|types}",
"property": "http://host1.in:7474/db/data/node/133/properties/{key}",
"self": "http://host1.in:7474/db/data/node/133",
"properties": "http://lhost1.in:7474/db/data/node/133/properties",
"outgoing_typed_relationships": "http://host1.in:7474/db/data/node/133/relationships/out/{-list|&|types}",
"incoming_relationships": "http://host1.in:7474/db/data/node/133/relationships/in",
"extensions": {
},
"create_relationship": "http://host1.in:7474/db/data/node/133/relationships",
"paged_traverse": "http://host1.in:7474/db/data/node/133/paged/traverse/{returnType}{?pageSize,leaseTime}",
"all_relationships": "http://host1.in:7474/db/data/node/133/relationships/all",
"incoming_typed_relationships": "http://host1.in:7474/db/data/node/133/relationships/in/{-list|&|types}"
}]
Regards,
Jayendra
You can try following way. Inside the for loop get the data node as JSONObject. From that data node you can extract every property. I just extracted mother name from data.
JSONObject data = (JSONObject) jsonObject.get("data");
final String motherName = (String) data.get("MOTHERS_NAME");
What library are you using to parse JSON ? I'd recommend that you use Jackson
For eg: To get the data you read from the file in a Map, you can write a method like this.
#SuppressWarnings("rawtypes")
public static Map toMap(Object object) throws JsonProcessingException{ ObjectMapper mapper = new ObjectMapper();
return mapper.convertValue(object, Map.class);
}

Categories