I am using Retrofit to fetch data from an API which returns JSON Objects in this format:
{
"error": 0
"message": "Request Successful"
"data": [ ... ]
}
I fetch it with GSON to POJO with these classes:
public class SearchResponse {
#SerializedName("error")
#Expose
private Integer error;
#SerializedName("message")
#Expose
private String message;
#SerializedName("data")
#Expose
private List<SearchResult> data;
(Getter and Setter here)
}
public class SearchResult {
#SerializedName("name")
#Expose
private String name;
#SerializedName("id")
#Expose
private Integer id;
....
(Getter and Setter here)
}
The problem is, that for every request I make I have to make two new Classes, even though the outer Class always contains the same three Variables: "error", "message" and "data". Is there any way to use the same Parent for every child without completely removing it? (I still need the "message" field)
You can use generics:
public class SearchResponse<T> { // T is a type variable
#SerializedName("error")
#Expose
private Integer error;
#SerializedName("message")
#Expose
private String message;
#SerializedName("data")
#Expose
private List<T> data; // We have a list of T
(Getter and Setter here)
}
You would deserialize like:
Type t = new TypeToken<SearchResponse<SearchResult>>(){}.getType();
SearchResponse<SearchResult> response = gson.fromJson(jsonString, t);
You would still have to make a TypeToken for each child type though.
Related
I want to ignore a boolean value when sending request all other data types work fine but boolean is set to false by default and is sent even when endpoint doesn't accept it ..
NOTE: I don't want to use transient in GSON because other endpoints accept that boolean value
public class UserModel implements Parcelable {
#SerializedName("agePrivate")
#Expose
private boolean agePrivate;
#SerializedName("username")
#Expose
private String username;
#SerializedName("_id")
#Expose
private String _id;
#SerializedName("user_id")
#Expose
private String user_id;
#SerializedName("email")
#Expose
private String email;
#SerializedName("phone")
#Expose
private String phone;
#SerializedName("birthdayDate")
#Expose
private String birthdayDate;
#SerializedName("job")
#Expose
private String job;
#SerializedName("image")
#Expose
private String image;
#SerializedName("location")
#Expose
private LocationModel location;
private String freind_status;
It's pretty simple, boolean primitive type's default value is always false, You should replace boolean by it's equivalent object type which is Boolean and it's default value is null and null will be ignored by Gson.
So replace:
#SerializedName("agePrivate")
#Expose
private boolean agePrivate;
with
#SerializedName("agePrivate")
#Expose
private Boolean agePrivate;
You can switch to different approach like sending the data value by value by extracting values from the object.
#GET("/endpoint")
Call<List<model>> getdata(#Field("location") String var, ....);
Call that on creating object of call like this
Call<List<model>> call = interface.getdata(obj.getLocation(),...);
Then it will be easy to do this.
I am trying to make several POJOs using Json.fromJson, to parse a String json to a POJO.
To make this I have the following class:
public class Queue {
#SerializedName("reference")
#Expose
private String reference;
#SerializedName("type")
#Expose
private QueuesTypes type;
#SerializedName("desc")
#Expose
private String desc;
#SerializedName("alias")
#Expose
private String alias;
private QueueObjects queueObjects;
}
As you can see all objects have their notations less the last because in this case is not the same.
Sometimes that label should be calls, or whatsapps or tweets, according to the information.
And this Queue Object that can has different attributes to the last object because is merged in the response like this:
{"success":true,"data":[
{"reference":"","type":"","desc":"","alias":"","calls":[{fromPhone:'', toPhone:''}]},
{"reference":"","type":"","desc":"","alias":"","whatsapps": [message:'']},
{"reference":"","type":"","desc":"","alias":"","calls":[fromPhone:'', toPhone:'']},
{"reference":"","type":"","desc":"","alias":"","calls":[fromPhone:'', toPhone:'']},
{"reference":"","type":"","desc":"","alias":"","whatsapps": [message:''],}
{"reference":"","type":"","desc":"","alias":"","fax": [fromFax:'', toFax:'', message:'']}]
So this is a:
public class SocketQueueResponse {
#SerializedName("success")
#Expose
private boolean success;
#SerializedName("data")
#Expose
private List<Queue> listQueue;
}
The problem is how can put several attributes with its several kind ob objects according to the response in QueueClass.
Now I have
public interface QueueObjects {
}
And another class according to the response, but the problem is how can set the notation to QueueObjects.
Thanks.
First off, I want to say that I extensively searched how to do this, using the advice from (at the very least) the following links:
Parsing JSON array that contain objects with different attributes with Retrofit
https://medium.com/#dds861/json-parsing-using-retrofit-and-recycleview-2300d9fdcf15
http://instinctcoder.com/android-studio-parsing-json-using-retrofit/
How to parse multiple JSON arrays inside a JSON object using Gson?
Using Retrofit to access JSON arrays
How to parse list of JSON objects surrounded by [] using Retrofit and GSON?
However, all of the above links show how to parse JSON objects/arrays with the same type of objects, or objects within just one array.
Here is the specific JSON data I'm working with:
{
"coord":{
"lon":-83.92,
"lat":34.08
},
"weather":[
{
"id":500,
"main":"Rain",
"description":"light rain",
"icon":"10d"
}
],
"base":"stations",
"main":{
"temp":292.16,
"pressure":1011,
"humidity":64,
"temp_min":290.15,
"temp_max":294.15
},
"visibility":16093,
"wind":{
"speed":3.6,
"deg":290,
"gust":7.7
},
"clouds":{
"all":90
},
"dt":1524609300,
"sys":{
"type":1,
"id":809,
"message":0.0057,
"country":"US",
"sunrise":1524567171,
"sunset":1524615295
},
"id":420007383,
"name":"Athens",
"cod":200
}
I converted it all to pojo using jsonschema2pojo.org. My question is, how can I use retrofit to access a variable like "main" inside the Weather object, when I already have a "main" object in the JSON array?
For that matter, how can I access any of the inner objects using Retrofit?
I have made the variables all serializable, and experimented using static classes for the objects within the array.
As an example, say I want to retrieve "id" within the "weather" object. My JSONResponse class looks like this:
public class JSONResponse {
#SerializedName("weather")
#Expose
private List<Weather> weather = null;
#SerializedName("main")
#Expose
private Main main;
#SerializedName("wind")
#Expose
private Wind wind;
#SerializedName("clouds")
#Expose
private Clouds clouds;
#SerializedName("sys")
#Expose
private Sys sys;
#SerializedName("name")
#Expose
private String name;
//getter and setter methods
}
And my Weather class looks like this:
public class Weather {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("main")
#Expose
//This describes what the weather is like, e.g. clear or cloudy
private String main;
#SerializedName("description")
#Expose
private String description;
#SerializedName("icon")
#Expose
private String icon;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getMain() {
return main;
}
public void setMain(String main) {
this.main = main;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
}
How would I retrieve that data using Retrofit in my main activity?
Would I be better off just using RXJava without Retrofit? If so, how can I go about doing that?
Thanks in advance to anyone who has the patience to answer this question.
I have the following xml
<MyPojo>
<name>Jason</name>
<age>25</age>
<meta>
<occupation>Engineer</occupation>
</meta>
</MyPojo>
I need to deserialize it to the following POJO:
public class MyPojo {
private String name;
private int age;
private String occupation;
}
The problem here is that occupation is wrapped within meta element
You need one more object:
public class MyPojo {
private String name;
private int age;
private Meta meta;
}
public class Meta{
private String occupation;
}
My idea is to replace occupation with an own class. Something like myMeta or whatever you want to call it(be aware in your case like the xml says: meta). This class should cotain the field occupation:
public class Meta
{
private String occupation;
}
After that you only have to add a new field of your new class e.g. myMeta to myPojo. Something like this:
public class MyPojo
{
private String name;
private int age;
private Meta meta;
}
this should avoid
that occupation is wrapped within meta element
Hope that helps!
I have json like following picture.
I have created 3 classes for this json.
First one is Main Class which is called KategoriResult
public class KategoriResult{
private String ErrorMessage;
private String ResultCode;
private List<KategoriItem> Payload;
..
..
getter - setter
..
Second KategoriItems
public class KategoriItem implements Serializable{
private int RowIdx;
private int Id;
private String Title;
private String Type;
private String WebUrl;
private List<ChildrenItem> Children;
private Boolean VideoItems;
..
..
getter - setter
..
and ChildrenItems
public class ChildrenItem implements Serializable{
private int RowIdx;
private int Id;
private String Title;
private String Type;
private String WebUrl;
private Boolean Children;
private Boolean VideoItems;
..
..
getter - setter
..
I am trying to convert the json above to java object with gson. I am getting following error : E/AndroidRuntime(1510): com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 7729.
HOw can I fix this?
java:
private List ChildrenList;
json:
Children : []
May be you should rename "ChildrenList" <-> "Children". What setter name do you use?