Parsing JSON with GSON - android

I'm having some trouble with GSON, mainly deserializing from JSON to a POJO.
I have the following JSON:
{
"events":
[
{
"event":
{
"id": 628374485,
"title": "Developing for the Windows Phone"
}
},
{
"event":
{
"id": 765432,
"title": "Film Makers Meeting"
}
}
]
}
With the following POJO's ...
public class EventSearchResult {
private List<EventSearchEvent> events;
public List<EventSearchEvent> getEvents() {
return events;
}
}
public class EventSearchEvent {
private int id;
private String title;
public int getId() {
return id;
}
public String getTitle() {
return title;
}
}
... and I'm deserializing with the following code, where json input is the json above
Gson gson = new Gson();
return gson.fromJson(jsonInput, EventSearchResult.class);
However, I cannot get the list of events to populate correctly. The title and id are always null. I'm sure I'm missing something, but I'm not sure what. Any idea?
Thanks

OK, I figured this out. I attest this to a long day of coding with little sleep the night before!
The "events" data structure contained multiple "events", which each contain an "event" type. I had to move the EventSearchEvent under a new class called EventContainer. This event container contained one field "event". This "event" was the "EventSearchEvent". THerefore, when GSON iterated over the JSON array, it saw the Container (which is of type "events") and then inside of that object it looked for a "event" member. When it finally found that it loaded up the id and title appropriately.
The short of it: I didn't have my object hierarchy built correctly.

Related

Is it possible to serialize and deserialize an object that contain an object as a variable in Firebase?

I am trying to structure my databases, and I was wondering if it's possible to deserialize an object from Firebase RealDatabase with the following structure.
public class Profile{
private String userID;
private TenantProfile tenant;
}
public class TenantProfile{
private String name;
private Room room;
}
public class Room{
private String town;
private int size;
}
Can the entire object Profile from Firebase be deserialized from a single query?
I just want to make sure that this is possible before refactoring my code and changing the references to the database.
Thanks in advance.
The Firebase database serializes/deserializes any public fields, and public properties that follow JavaBean naming conventions for getters and setters. Since the classes you show contain neither of those, they will not read or write any data.
If you mark the fields as public or add public getters/setters, then writing an instance of the Profile class will generate this JSON:
"userID": {
"tenant": {
"name": "the name",
"room": {
"town": "the town",
"size": 42
}
}
}
And that's also the format you'll need to have in the database to read the value back.

How can i create an array that contains another array?

I need to save some values that i get it from a listview, my question is how can i do this implementation to save my values?
I need to do this.
[
{
"id_question": "my value here",
"answers": [
{
"my_answer":"value for this answer",
"id_answer":"my value here"
},
{
"my_answer":"value for this answer",
"id_answer":"my value here"
}
]
}
]
Recently i use
List<Map<String, String>[]> listOfMaps = new ArrayList<Map<String, String>[]>();
Answer.java
public class Answer {
private String myAnswer;
private String idAnswer;
//constructor, setters and getters
}
Question.java
public class Question {
private String question;
private List<Answer> answerList;
//constructor, setters and getters
}
In your current class
private List<Question> questionList;
If what I understand by the term “saving” in your question as saving to local db, then these classes can directly be converted to Realm Classes.
P.S. Simple way to get to this data structure is to stick to basics. That is objects are representation of real time entity.

Parse JSON attribute "data" using gson and retrofit2 in fancy way

Well, I've seen alot of boilerplate code in my model classes when I need to parse json using GSON with Retrofit2. I would like to find out how to deal with it, because I'm pretty sure there is a way to make this look more elegant.
{
"data": [
{
"id": 2,
"price": 56,
"name": "Hello"
}
]
}
For parsing this json I would need to create 2 model classes. One would be for the inner object (id, price, name) and one would be Data.class which holds one attribute - List of this inner object.
It's totally okay to have different inner objects inside, but later on you will have many "Data.class" which has one attribute "data" which is List, but with different inner object type. How can I avoid this boiler-plate Data lookalike classes in my projects?
What I want:
Is to NOT create new Data class with "data" attribute changing inner object type whenever I create new "inner" object model class.
I had this problem and fix that with create one abstract class with name BaseResponse like this
public abstract class BaseResponseInterface2<T> {
#SerializedName("data")
private List<T> data;
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
}
And use that like this in api service interface
#GET("/api/")
Call<BaseResponseInterface2<innerClass>> getResponse(
#Path("id") int id
);
Hope it help

Does Retrofit support keypath on json parsing or something alike?

For example i have json looks like:
{
"data": [
{
"name": "one"
},
{
"name": "two"
}
]
}
For example i have object User with field name.
Is it possible write method which will parse data array to objects User?
something like
Call<List<User>> getUsers(#KeyPath("data"))
Now to do this, i need create a wrapper class something like
public class UsersWrapper {
#SerializeName("data")
public ArrayList<User> users;
}
and in service i do next
public interface Service {
#GET("users")
Call<UsersWrapper> getUsers()
}
But my all requests is just response with data but variable objects in array.
In this case i need create wrappers to any data requests. Pain :(
?
I'd do it this way:
Global class Wrapper<T> to parse the whole JSON
public class Wrapper<T> {
public List<T> data;
}
And User to parse actual array;
public class User {
public String name;
}
Then, the API interface:
#GET("/people")
Wrapper<User> getUsers();
And in DataSource class just do something like this:
#Override
public List<User> getUsers() {
Wrapper<User> usersWrapper = myApiInterface.getUsers();
return usersWrapper.data;
}
Upd1:
Another solution is to create custom JsonDeserializer (like described here) for List<User> type, register by registerTypeAdapter it with your custom Gson object and then you can deserialise your Json directly into List<User>. Though, this solution brings much more extra code and potential benefit is unclear for me.

Retrofit returns valid list but items members are null

I have a problem pretty much the same as this: retrofit returning valid json but pojo is empty
But my variables are not declared as static. The are all declared like:
#SerializedName("name")
#Expose
private String name;
I have tried removing the annotations, but that doesn't work.
what could be the problem?
EDIT:
Interface:
#GET("/MyController/MyAction/{name}")
void getSomeData(#Path("name") String name, Callback<List<DataItem>> cb);
Can you show me the actual received data(JSON or XML)? It seems that your callback structure is not matching with your data. For example, it would be possible that your data may have array that have a name, and you ignored it.
In my case, I declared like this,
void getList(#Path("data") String data,//
Callback<OrderList> callback);
OrderList is:
public class OrderList {
List<Order> order_list;
}
And my data is:
{
"order_list":
[
{ "id": "1001", "data": "a" },
{ "id": "1002", "data": "b" }
]
}
I mean, it seems that your data may have nested structure and your class may not matching with that.

Categories

Resources