JSON parse using Gson giving null - java

I am trying to parse a JSON response documents using Gson but after parse it's giving me a null value
My JSON response is a Array of Documents
Java Code
//Code to convert the response into JSON
String res = gson.toJson(results);
//Parse the JSON
java.lang.reflect.Type collectionType = new TypeToken<List<Objects.JsonResponse>>() {}.getType();
List<Objects.JsonResponse> resp = gson.fromJson(res, collectionType);
System.out.println(resp.get(2).getName());
JAVA Object
package Objects;
import java.util.List;
import com.google.gson.annotations.SerializedName;
public class JsonResponse {
#SerializedName("product_id")
public static String product_id; //17
#SerializedName("create_date")
public static String create_date; //45
#SerializedName("image_small")
public static String image_small; //85
#SerializedName("image_large")
public static String image_large; //133
#SerializedName("name")
private static String name; //174
#SerializedName("description")
public static String description; //266
#SerializedName("tagline")
public static List<String> tagline;
#SerializedName("category")
public static List<String> category;
#SerializedName("catlevel0")
public static List<String> catlevel0;
#SerializedName("catlevel1")
public static List<String> catlevel1;
#SerializedName("catlevel2")
public static List<String> catlevel2;
#SerializedName("color")
public static List<String> color;
#SerializedName("size")
public static List<String> size;
#SerializedName("_version_")
public static String _version_;
#SerializedName("product_id")
public static String getName() {
return name;
}
public static void setName(String name) {
JsonResponse.name = name;
}
}
JSON document to be parsed is:
[
{
"product_id": "prod3400008",
"create_date": "2011-02-17T00:00:00Z",
"image_small": "/hul_images/small/17_Rexona.jpg",
"image_large": "/hul_images/large/17_Rexona.jpg",
"name": "Small Shell Cluster Loop Earrings",
"description": "Small Shell Cluster Loop Earrings",
"tagline": [
"B1G1 75% Off Jewelry "
],
"category": [
"Earrings"
],
"catlevel0": [
"Accessories"
],
"catlevel1": [
"Jewelry"
],
"catlevel2": [
"Earrings"
],
"color": [
"Clearly Coral",
"Mocha Brown",
"Blue Lagoon",
"Hunter Green",
"Medium Purple"
],
"_version_": 1527034576315089000
}
]

This is not a solutions, more like a tip. I found out the problem in your question. The problem is with the json array. If you remove all the arrays and just an object, this problem wont come. I dont know if you are aware of that already.
Please try the following json
{
"product_id": "prod3400008",
"create_date": "2011-02-17T00:00:00Z",
"image_small": "/hul_images/small/17_Rexona.jpg",
"image_large": "/hul_images/large/17_Rexona.jpg",
"name": "Small Shell Cluster Loop Earrings",
"description": "Small Shell Cluster Loop Earrings",
"_version_": 1527034576315089000
}
I removed all the arrays.
I have also removed the static declaration of your class JsonResponse, and static declaration of all your member variables.
And this is try this code:
Gson gson = new Gson();
String res = gson.toJson(results);
JsonResponse response = gson.fromJson(results, JsonResponse.class);
System.out.println(response.product_id);
System.out.println(response.create_date);
Hope this will help to figure out the problem. If you still cant find out, let me know... I will try harder... :-)

Object attributes are static and you should tell the GsonBuilder to serialize it.
follow this stack for more information.
Better practice would be not to make pojo class filed as static :)

Maybe it's giving you null because you messed up your annotations...
Also, remove static from all the methods and fields, you are trying to make instance variables, not class variables.
#SerializedName("product_id") // <---- not right
public String getName() { // <--- removed "static"
return name;
}

Related

Unable to map API response to pojo

I have a json response
"data": {
"students": [
{
"id": 100,
"name": "ABC"
},
{
"id": 101,
"name": "XYZ"
}
I need to map it to my pojo, something like -
public class TempClass {
List<Temp> list_students;
}
class Temp {
Long id;
String name;
}
Direct reading API response into my pojo gives me a class cast exception. I've tried converting response to a list of map and the collect as Temp class but that also doesn't work.
Exception -
java.util.LinkedHashMap cannot be cast to java object
Any suggestions please?
Code snippet for conversion -
new TempClass(((LinkedHashMap<String, Object>) response.getData()).entrySet())
.stream().map(map -> mapper.convertValue(map, Temp.class))
.collect(Collectors.toList()))
public class Data{
public ArrayList<Student> students;
}
public class Root{
public Data data;
}
public class Student{
public int id;
public String name;
}
Your POJO class will look like this

Deserialize json nested object in android

I am in trouble. I can not deserialize this object that I return json from an http request. Can anyone help me?
I downloaded and added to the libs folder gson_2.2.4.jar.
We insert the object json
{
"returnCode": 0,
"data": [
{
"token": "aaaaa =",
"code": "xx",
"id": ""
}
],
"errorMsg": ""
}
You need to create a class of data object, for example
public class DataObj {
public String token;
public String code;
public String id;
}
and then create another class for the whole json, for example
public class MyObj {
public int returnCode;
public DataObj[] data;
public String errorMsg;
}
then create an object of MyObj and use deserializer from GSON to read json,
for example:
GSON gson = new GSON();
MyObj newMyObj = gson.fromJson(jsonString, MyObj.class);
Where jsonString contains the json object as string.
(#Shivam Verma thanks for your edit)

How to convert Json String with dynamic fields to Object?

I have the followed snipets of Json String:
{
"networks": {
"tech11": {
"id": "1",
"name": "IDEN"
},
"tech12": {
"id": "2",
"name": "EVDO_B"
}
}
}
I use some methods to convert this String to Object:
private static Gson mGson = new Gson();
...
public static WebObjectResponse convertJsonToObject(String jsonString) {
WebObjectResponse webObjectResponse = null;
if(jsonString != null && jsonString.length() > 1){
webObjectResponse = mGson.fromJson(jsonString, WebObjectResponse.class);
}
return webObjectResponse;
}
Where WebObjectResponse is class that should represent above mentioned String.
Its not complicated if I get static fields.
But in my case the values have different names: tech11, tech12 ....
I can use #SerializedName but its works in specific cases like convert "class" to "class_".
As you see networks Object defined as list of tech Objects but with different post-fix.
public class WebObjectResponse{
private DataInfoList networks = null;
}
This is static implementation, i defined 2 values tech11 and tech12 but next response might be techXX
public class DataInfoList {
private DataInfo tech11 = null;
private DataInfo tech12 = null;
}
public class DataInfo {
private String id = null;
private String name = null;
}
What is the good way to convert current Json String to Object where list of elements are Objects too and have different names?
Thank you.
Use a Map!
I would do the following
public class WebObjectResponse {
private Map<String, DataInfo> networks;
}
public class DataInfo {
private String id = null;
private String name = null;
}
// later
Gson gson = new Gson();
String json = "{\"networks\": {\"tech11\": { \"id\": \"1\",\"name\": \"IDEN\" }, \"tech12\": { \"id\": \"2\", \"name\": \"EVDO_B\" } }}";
WebObjectResponse response = gson.fromJson(json, WebObjectResponse .class);
For each object in json networks, a new entry will be added to the Map field of your class WebObjectResponse. You then reference them by techXX or iterate through the keyset.
Assuming a structure like this
{
"networks": {
"tech11": {
"id": "1",
"name": "IDEN"
},
"tech12": {
"id": "2",
"name": "EVDO_B"
},
"tech13": {
"id": "3",
"name": "WOHOO"
}, ...
}
}
We would need your class structure for more details.
As far as I am aware, I think you will need to have some mappings defined somewhere (I used xml's) and then try to match json with one of the mappings to create objects.
Google gson is good. I did it in Jackson
Also, converting objects should be trivial. But since you might have variable fields like tech11 and tech12 , you might want to store the "network" value as a string and then extract fields out of it when required.
Hope I could help.
Edit : Sotirious nails it.
Please use this link for converting SON Response to Java POJO class
http://www.jsonschema2pojo.org/

What is the data structure of this JSON?

I'm trying to parse Json to Java by using Gson, but when I use fromJson(), I always get null. Who can explain this data structure for me? Thanks!
{
"d": {
"results": [
{
"__metadata": {
"uri": "https://api.datamarket.azure.com/Data.ashx/Bing/SearchWeb/v1/Web?Query='bill'gates'&$skip=0&$top=1",
"type": "WebResult"
},
"ID": "9bd0942f-fe5b-44fc-8343-ef85e5b93a7e",
"Title": "The Official Site of Bill Gates - The Gates Notes",
"Description": "In the space between business and goverment, even a small investment can make a big impact on the lives of those in need.",
"DisplayUrl": "www.thegatesnotes.com",
"Url": "http://www.thegatesnotes.com/"
},
{
"__metadata": {
"uri": "https://api.datamarket.azure.com/Data.ashx/Bing/SearchWeb/v1/Web?Query='bill'gates'&$skip=1&$top=1",
"type": "WebResult"
},
"ID": "fdf0d3b9-b29f-43ef-b5ba-6bb4b1b04458",
"Title": "Bill Gates - Wikipedia, the free encyclopedia",
"Description": "William Henry \"Bill\" Gates III (born October 28, 1955) is an American business magnate and philanthropist. Gates is the former chief executive and current chairman of ...",
"DisplayUrl": "en.wikipedia.org/wiki/Bill_Gates",
"Url": "http://en.wikipedia.org/wiki/Bill_Gates"
}
],
"__next": "https://api.datamarket.azure.com/Data.ashx/Bing/SearchWeb/v1/Web?Query='bill'gates'&$skip=10&$top=10"
}
}
I think the data structure should be like this, but it doesn't work.
public class d {
public result[] results;
public String __next;}
public class result {
public information[] infolist;}
public class information {
public __metadata metadata;
public String ID;
public String Title;
public String Description;
public String DisplayUrl;
public String Url;}
public class __metadata {
public String uri;
public String type;}
Your Information class is the problem. Put the Information stuff into Result and remove the infolist from Result. Also, the field name for the meta data is __metadata. This isn't the class name. Lastly, you're missing a class to wrap d as a field.
public class DataContainer {
public Data d;
}
public class Data {
public Result[] results;
public String __next;
}
public class Result {
public Metadata __metadata;
public String ID;
public String Title;
public String Description;
public String DisplayUrl;
public String Url;
}
public class Metadata {
public String uri;
public String type;
}
You really should use common convention for class names. Gson won't preclude you from using your own names for classes. It only requires control for the name of the fields.
To deserialize:
String json = ... ;
DataContainer myDataContainer = new Gson().fromJson(JSONString , DataContainer.class);
Result[] myResult = myDataContainer.d.results;
Try that and see if that works.
Here's how you should interpret the JSON when you're writing a class structure around it for Gson:
An opening { indicates an object, so this will be a new class (or an existing one if they have the same fields)
A "this": indicates a field for the object it's inside, and the field must be named the same thing as the text in the string.
An opening [ indicates an array, a List, or a Set (Result[] results could just as easily be List<Result> results)

Using Gson to unserialize an array of objects

I have a JSON response that looks like this. I want to extract the values of "text" and put them into a Set of Strings (i.e. I don't necessarily need the entire JSON to be derialised).
I am using the GSON library
So far my method looks like this (It's obviously wrong):
public static Response deserialise(String json){
Gson gson = new Gson();
Response r = gson.fromJson(json, Response.class);
return r;
}
I am calling deserialise with this:
Response r = deserialise(json);
System.out.println("[status]: "+r.getStatus()); // works fine
Collection<Keyword> coll = r.getKeywords();
Iterator<Keyword> itr = coll.iterator();
while(itr.hasNext()){
System.out.println(itr.next().getWord()); //prints null every time
}
Response is a class with the following member variables (with getters and setters):
private String status;
private String usage;
private String language;
private Collection<Keyword> keywords;
Keyword is a class with the following member variables (with getters and setters):
private String word;
private String relevance;
The JSON looks like this:
{
"status": "OK",
"usage": "By accessing AlchemyAPI or using information generated by AlchemyAPI, you are agreeing to be bound by the AlchemyAPI Terms of Use: http://www.alchemyapi.com/company/terms.html",
"url": "http://www.theage.com.au/world/aussie-trying-to-make-a-difference-gunned-down-20110510-1egnv.html",
"language": "english",
"keywords": [
{
"text": "Mr McNichols",
"relevance": "0.99441"
},
{
"text": "Ms Benton",
"relevance": "0.392337"
},
{
"text": "Detroit",
"relevance": "0.363931"
},
{
"text": "Crocodile Hunter",
"relevance": "0.350197"
}
]
}
The problem is that the Collection of Keywords returns null values - although it seems to have the correct size, which is positive.
This just works:
public class Keyword {
public String text;
public String relevance;
}
public class MyJSON {
public String status;
public String usage;
public String language;
public Collection<Keyword> keywords;
}
In the main method
String str = "{\"status\": \"OK\","+
"\"usage\": \"By accessing AlchemyAPI or using information generated by AlchemyAPI, you are agreeing to be bound by the AlchemyAPI Terms of Use: http://www.alchemyapi.com/company/terms.html\","+
"\"url\": \"http://www.theage.com.au/world/aussie-trying-to-make-a-difference-gunned-down-20110510-1egnv.html\","+
"\"language\": \"english\","+
"\"keywords\": ["+
"{"+
"\"text\": \"Mr McNichols\","+
"\"relevance\": \"0.99441\""+
"},"+
"{"+
"\"text\": \"Ms Benton\","+
"\"relevance\": \"0.392337\""+
"},"+
"{"+
"\"text\": \"Detroit\","+
"\"relevance\": \"0.363931\""+
"},"+
"{"+
"\"text\": \"Crocodile Hunter\","+
"\"relevance\": \"0.350197\""+
"}"+
"]"+
"}";
Gson gson = new Gson();
MyJSON mj = gson.fromJson(str, MyJSON.class);
System.out.println(mj.language);
for(Keyword k: mj.keywords)
System.out.println(k.text+":"+k.relevance);
This prints
english
Mr McNichols:0.99441
Ms Benton:0.392337
Detroit:0.363931
Crocodile Hunter:0.350197
Look carefully at my Keyword class!(and my JSON string starts with {).
This was all down to my own stupidity.
In the keyword class I called the variable word when it should have been text in order to map properly to the JSON.

Categories

Resources