Parsing JSON result with Gson - java

I have an InputStreamReader reader that contains this JSON file:
http://barcelonaapi.marcpous.com/bus/nearstation/latlon/41.3985182/2.1917991/1.json
Also, I have a class Station that contains ID, streetName, city, utmX, utmy, lat, lon as members.
What should i do, if I want parse the JSON file with GSon, to return an List<Station>?
I tried this :
gson.fromJson(reader, new TypeToken<List<Station>>(){}.getType());
But it raised an IllegalStateException (Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2).
How to extract only data which interests me (members of my Station class)?
Is it possible with GSon, or I need to use the JSON standard API provided by Android SDK (with JSONObject and JSONArray)?

You're close, but in this case you can't directly map to a List<Station> because it is wrapped in json object (2 layers deep) that also contains some other fields. That's basically also what the error is trying to tell you: you're instructing Gson to map to an array/list of items (in json: [...]), but instead it encountered an object (in json: {...}).
The quickest solution is to create a POJO that reflects this json response. For example:
public class Response {
#SerializedName("code") public int mCode;
#SerializedName("data") public ResponseData mData;
}
public class ResponseData {
#SerializedName("transport") public String mTransport;
#SerializedName("nearstations") public List<Station> mStations;
}
Now you can map the json to the above Response and get the List<Station> from the result:
Response response = gson.fromJson(reader, Response.class);
List<Station> stations = response.mData.mStations;
// do something with stations...
If you like to do something a little more advanced, you can take a look into writing a custom deserialiser or type adapter.

Related

How to parse JSON String in Java to get String anotherJSON which is contained inside

I am getting String jsonObject in my controller.
The structure is following:
{
"name":"name",
"schema": {
...
...
}
}
I need to parse it into a Plain Old Java Object and receive schema as a String (saving the structure). When I am using System.out.print("schema"), I expect to see:
{
...
...
}
I have a POJO Collection with String name and Object schema fields.
I am using GSON to get Collection.class from String json:
new Gson().fromJson(json, Collection.class);
When I try to print Collection.schema I get the following output:
{......} - in a one row.
I really need to get this object as a String without formatting
This should work. Basically, you hydrate your Collection object and then just send your schema back through Gson. Done.
Gson gson = new Gson();
Collection collection = gson.fromJson(json, Collection.class);
String schema = gson.toJson(collection.getSchema());
System.out.println(schema);
Question could be asked as to why you are accepting a String from your controller? Perhaps you can get the framework you are using to pass in a fully converted Collection object and save yourself a step?
Also, for your Collection.schema, it's common to use Map<String, Object> instead of Object for this type of "schema"-less type of paradigm.

How can I deserialize JSON to an object with a HashMap attribute?

Right now I am using Gson to deserialize JSON to Object.
The JSON looks like this:
[
{
"hash":"c8b2ce0aacede58da5d2b82225efb3b7",
"instanceid":"aa49882f-4534-4add-998c-09af078595d1",
"text":"{\"C_FirstName\":\"\",\"ContactID\":\"2776967\",\"C_LastName\":\"\"}",
"queueDate":"2016-06-28T01:03:36"
}
]
And my entity object looks like this:
public class AppCldFrmContact {
public String hash;
public String instanceid;
public HashMap<String,String> text;
public String queueDate;
}
If text was a String data type, everything would be fine. But then I wouldn't be able to access different fields as I want to.
Is there a way to convert given JSON to Object I want?
The error I am getting is: Expected BEGIN_OBJECT but was STRING at line 1 column 174, which is understandable if it cannot parse it.
The code doing the parsing:
Type listType = new TypeToken<List<AppCldFrmContact>>() {
}.getType();
List<AppCldFrmContact> contacts = gson.fromJson(response.body, listType);
For you expected result, JSON data should be like below format,
[
{
"hash":"c8b2ce0aacede58da5d2b82225efb3b7",
"instanceid":"aa49882f-4534-4add-998c-09af078595d1",
"text":{"C_FirstName":"","ContactID":"2776967","C_LastName":""},
"queueDate":"2016-06-28T01:03:36"
}
]
You are getting this error because text field is a JSON map serialized to the string. If it is an actual your data and not a just an example, you can annotate a field with #JsonDeserialize and write your own custom JsonDeserializer<HashMap<String,String>> which will make deserialization 2 times.

Deciding POJO java class for JSON payload after inspecting JSON in list in Retrofit

I have a JSON payload coming from the server which is a list of Objects. I need a way to get the response and then check each object for a particular attribute and then decide which POJO object to decode each of those. I have checked StackOverflow and I have come across solutions like :
Gson gson = new Gson();
String json = response.getBody().toString();
if (checkResponseMessage(json)) {
Pojo1 pojo1 = gson.fromJson(json, Pojo1.class);
} else {
Pojo2 pojo2 = gson.fromJson(json, Pojo2.class);
}
here the json string is the entire string which is a list of objects, i need to drill down into the list, check an attribute in the object to determine which POJO to use. Any pointers or help appreciated! Thanks!

How to check json for key and if it exists then set the value in java model Object

I have a model object which is initialized with default values. To refresh the content of object I call an web service and get the response and get the content from json object.
I want to check If json response contains the object or not. If it does then call the setter and set the data and if it doesn't then leave then don't set it. I have approx 300 fields in my object. How I can do it with less code. I am listing my current approach.
My Model object is like
public class MyObject {
private String str1 = "Initial Value1";
private String str2 = "Initial Value2";
public void setStr1(String str1)
{
this.str1 = str1;
}
public void setStr2(String str2)
{
this.str2 = str2;
}
public String getStr1(){
return str1;
}
public String getStr2(){
return str2;
}
}
my json response be like
{
"val_one":"New Value1",
"val_two":"New_value2"
}
Now at run time I need to set the value from json response
MyObject myObject = new MyObject();
if(jsonObject.has("val_one"));
myObject.setStr1(jsonObject.get("val_one"));
if(jsonObject.has("val_two"));
myObject.setStr2(jsonObject.get("val_two"));
Now how to do it in a better and efficient
If both sides are using JAVA then why not just use json-io. You can create an object as normal. ie
Animal a = new Aminmal() andimal.setName("bob");
Then use json-io to make it into json -- stream to where ever it needs to be... use json io to change back to object
This can be done using
JsonWriter.objectToJson(Object o);
JsonReader.jsonToJava(String json);
https://code.google.com/p/json-io/
json-io is also extremely light weight and quicker than most if not all other third party json library's that I have used.
That being said if you want to have more control on the output ie.. date conversions etc.. then look at GSON.
https://code.google.com/p/google-gson/
Another option, in addition to the other suggestions is gson. Here the link for gson information.
Essentially the idea with gson being that you define an object to represent the JSON structure that you are receiving. So somewhat like what you have now, you'd just need to change the object attributes to match the names of the JSON fields, ie 'val_one' and 'val_two'.
Then you just need to use gson to create the object from the JSON text, eg:
Gson gson = new GsonBuilder().create();
MyObject json = gson.fromJson(jsonStr, MyObject.class);
Why do you want to take of the object model mapping yourself? If you take spring then you can use the jackson mapper and have it all done for you.
If you don't want to use spring then you still can use jackson2 and let it handle the parsing:
http://wiki.fasterxml.com/JacksonRelease20

Map generic JSON object to Map interface with GSON

Given the following JSON object
{
"id": 5,
"data: { ... }
}
Is it possible to map this to the following POJO?
class MyEntity {
int id;
Map<String, Object> data;
}
Because I would like to leave the data object open ended. Is this even possible or what is a better approach to go about this? I am doing this on Android.
I don't have any idea about Android application but you can achieve it using Gson library easily.
The JSON that is used in your post is not valid. It might be a typo. Please validate it here on JSONLint - The JSON Validator
Simply use Gson#fromJson(String, Class) method to convert a JSON string into the object of passed class type.
Remember the name of instance member must be exactly same (case-sensitive) as defined in JSON string as well. Read more about JSON Field Naming
Use GsonBuilder#setPrettyPrinting() that configures Gson to output Json that fits in a page for pretty printing.
Sample code:
String json = "{\"id\": 5,\"data\": {}}";
MyEntity myEntity = new Gson().fromJson(json, MyEntity.class);
String prettyJsonString = new GsonBuilder().setPrettyPrinting().create().toJson(myEntity);
System.out.println(prettyJsonString);
output:
{
"id": 5,
"data": {}
}

Categories

Resources