What is the data structure of this JSON? - java

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)

Related

Problem with model in Java for given JSON

I need to create a model in Java to deseralize such JSON.
[
{
"yyy": {
"address": "y-a",
"acronym": "YYY"
},
"xxx": {
"address": "x-a",
"acronym": "XXX"
}
},
{
"vvv": {
"address": "v-a",
"acronym": "VVV"
}
}
]
It looks for me that a model in Java will look like here (i'm using Jackson)
public class Yyy{
public String address;
public String acronym;
}
public class Xxx{
public String address;
public String acronym;
}
public class Vvv{
public String address;
public String acronym;
}
public class Root{
public Yyy yyy;
public Xxx xxx;
public Vvv vvv;
}
It is not acceptable at all because I don't know which keys like xxx, yyy, vvv I will get -
They are not defined and can be random. What I need to do to convert this JSON to have something usefull? I mean to have an array of objects and in inside object a map where keys will be created from keys in JSON (vvv, yyy, xxx)

Expected a string but was BEGIN_OBJECT at line 1 column 29 path

I am getting the following error:
java.lang.IllegalStateException: Expected a string but was
BEGIN_OBJECT at line 1 column 29 path $.entree[0].photo
It makes no sense to me because my json response should be constructed as follows:
import com.google.gson.annotations.SerializedName;
public class Entree {
#SerializedName("id")
public int id;
#SerializedName("photo")
public Entree.Photo photo;
public class Photo {
#SerializedName("url")
public String url;
#SerializedName("web")
public Entree.Photo.Web web;
#SerializedName("mobile")
public Entree.Photo.Mobile mobile;
public class Web {
#SerializedName("url")
public String url;
}
public class Mobile {
#SerializedName("url")
public String url;
}
}
}
JSON data:
"entrees": [
{
"id": 32,
"photo":
{
"url": "4c312e9aed37a59319096a03_1.jpg",
"web": {
"url": "web_4c312e9aed37a59319096a03_1.jpg"
},
"mobile": {
"url": "mobile_4c312e9aed37a59319096a03_1.jpg"
}
}
},
...
Do you see how Photo is an object and not a string in my class? What am I doing wrong then?
Try mark the inner class with static
In Gson document , it says
Gson can also deserialize static nested classes. However, Gson can not
automatically deserialize the pure inner classes since their no-args
constructor also need a reference to the containing Object which is
not available at the time of deserialization. You can address this
problem by either making the inner class static or by providing a
custom InstanceCreator for it.
Actually, your
GSON Serializable class is not correct,
For a JSON response like this,
{
"entrees": [{
"id": 32,
"photo": {
"url": "4c312e9aed37a59319096a03_1.jpg",
"web": {
"url": "web_4c312e9aed37a59319096a03_1.jpg"
},
"mobile": {
"url": "mobile_4c312e9aed37a59319096a03_1.jpg"
}
}
}]
}
The GSON class will be as,
public class Entree {
#com.google.gson.annotations.SerializedName("entrees")
public List<Entrees> Entrees;
public static class Web {
#com.google.gson.annotations.SerializedName("url")
public String Url;
}
public static class Mobile {
#com.google.gson.annotations.SerializedName("url")
public String Url;
}
public static class Photo {
#com.google.gson.annotations.SerializedName("url")
public String Url;
#com.google.gson.annotations.SerializedName("web")
public Web Web;
#com.google.gson.annotations.SerializedName("mobile")
public Mobile Mobile;
}
public static class Entrees {
#com.google.gson.annotations.SerializedName("id")
public int Id;
#com.google.gson.annotations.SerializedName("photo")
public Photo Photo;
}
}

JSON parse using Gson giving null

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

How to create pojo classes for json object that have integer keys?

I want to convert this json request to pojo:
{
"query": {
"pages": {
"101": {
"id": 101,
"title": "My book",
"index": 1,
"img": "xyz.com"
},
"102": {
"id": 102,
"title": "My book",
"index": 1,
"img": "xyz.com"
}
}
}
}
Json object inside pages object contains integer key and they are dynamic, i mean their key can be changed to other integer values. I used json www.jsonschema2pojo.org tool to create pojo classes but that doesn't solve my purpose because it will create two separate classes for object 101, 102 and these object can change their key's value. My Point is when I hit the api next time it will come like 104, 105 and so on. So please help me with this.
You should do something like this:
// Pojo class
public class Page{
private Integer id;
private String title;
private String img;
private Integer index;
public Integer getId(){return id;}
public void setId(Integer id){this.id = id;}
public String getTitle(){return title;}
public void setTitle(String title){this.title = title;}
public String getImg(){return img;}
public void setImg(String img){this.img = img;}
public Integer getIndex(){return index;}
public void setIndex(Integer index){this.index = index;}
}
if you nedded wrapper class
public class Pages{
List<Page> pages = new List<Page>();
// add
// remove
// etc
}
Json convertion with Jackson
List<Page> pages = mapper.readValue(jsonString, ypeFactory.collectionType(List.class, Page.class));
The easiest and best way to do so is to use this website http://www.jsonschema2pojo.org/
Why is it that easy?
You only have to paste the json schema to the website, and it will generate the required model classes. I have been using it for a long time, and never ever have I got a wrong modal class. It do have lots of features too.
Use third party tools for improving your productivity.

How to Parse Nested / Multiple Json Objects using Retrofit

The JSON I'm parsing looks like this:
{ "version": 1
"data": {
"1001": {
"id": 1001,
"name": "herp",
"into": [
"3111": "we"
]
},
"1032": {
"id": 1002,
"name": "derp",
"into": [
"36": "w",
"12341: "c"
],
"tags": [
"hi there"
],
"cost" {
"even": 15
}
},
"1603": {
"id": 1003,
"name": "her",
"into": [
"37": "dll",
"58": "eow",
"32145": "3a"
],
"cost" {
"highest": 325
"lowest": 100
}
},
.... Even more data
}
The Json that is within "data" goes on for a while and does not have a set endpoint. I have no control over the Json, I'm just trying to read it. Unfortunately, with my class code I'm unable to get it to work. When I make a retrofit call the information inside "data" is empty.
I've tried many iterations of implementing this, including using a deserializer and restructuring my POJO code. This is the current state of my Data class:
public class Data {
private Map<String, Item> itemData;
// Relevant Getters, Setters and Constructors //
}
For my Item Class, the main issue is that the JSON Content isn't set, it can vary at times. As you can see above the values inside "into" vary and sometimes the amount of things within item changes as well such as "tags" or "cost":
public class Item {
private int id;
private String name;
private String group;
private String description;
private Map<String, String> into;
private List<String> tags;
private Map<String, Integer> cost;
// Relevant Getters, Setters and Constructors //
When I use this code my data class is empty, I don't see any errors in the log so I can't seem to figure out why the GSON isn't working with this.
In case you wanted to see how I construct my RestClient, here it is:
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(ROOT)
.setClient(new OkClient(new OkHttpClient()))
.setLogLevel(RestAdapter.LogLevel.FULL);
RestAdapter restAdapter = builder.build();
REST_CLIENT = restAdapter.create(DataApi.class);
I know that my Rest Query works because I can get the content within "version" but everything inside data is null.
I am officially a dumb scrub and completely looked over the easiest possible fix and should have my account and developer title revoked.
This is all I should have done:
public class ItemGroup {
private String version;
private Map<String,Item> data;
//...Man i'm so dumb...
}
AS REFERENCE FOR THE FUTURE. The reason why this works is because the JSON is in this format { { } { } { } }. Which means you have 3 objects of objects, as opposed to { [ ] [ ] [ ] } which is 3 objects of a list. What I had done was treat { { } { } { } } as { { { } { } { } } }. Which is not correct. By using a map which is basically a collection of pairs, we are able to imitate the { { } { } { } } with a Map.
Map Object { {Key-Pair Object} {Key-Pair Object} {Key-Pair Object} }
Just a quick idea for your Pojos:
Not sure if this will work. Maybe write a custom deserializer.
public class YourResponse {
int version;
Data data;
class Data {
Subdata subData;
}
class Subdata {
private int id;
private String name;
private ArrayList<Into> into;
private ArrayList<String> tags;
//...
}
class Into {
// "3111": "we"
private String into;
}
}

Categories

Resources