Serialization of Custom Class Using GSON - android

I list of objects of a custom class which i am trying to serialize using json but the values once serialized are 0 and not the actual values that are stored in the list.
MyCustom Class
public class CustomClass extends RealmObject {
#Expose()
#SerializedName("startID")
private int startMessageID;
#Expose()
#SerializedName("endID")
private int endMessageID;
#Expose(serialize = false)
private boolean syncing = false;
}
The following is what i use to serialize the list.
GsonBuilder builder = new GsonBuilder();
builder.excludeFieldsWithoutExposeAnnotation();
Gson gson = builder.create();
Type listType = new TypeToken<List<CustomClass >>() {
}.getType();
Log.i("Json", gson.toJson(syncModelList, listType));
The above code produces an output of
[{"endID":0,"startID":0},{"endID":0,"startID":0}]
The structure is correct but my values are lost,i have checked the values before serialization and they are correct and exist.

It's because Gson can't serialize a managed Realm object. You need to convert it to an unmanaged object first, like this:
new Gson().toJson(realm.copyFromRealm(managedModel));
Have a look at this answer for a full explanation Android: Realm + Retrofit 2 + Gson

Related

Custom GSON parser exclude object instances based on property value

When parsing JSON in Android using the GSON parser, I'd like to implement a rule that will exclude any objects from being created based on property value. For example:
{"people": [
{"first_name": "Bob"},
{"first_name": "Bob", "last_name": "Loblaw"}]}
I want to exclude the first person object because it doesn't have a last name property.
Is this possible at parse time?
It is possible with JsonDeserializer.
Suppose you would have POJOs like
public class Response {
#Getter
private List<Person> people = new ArrayList<>();
}
and
public class Person {
#Getter #Setter
private String first_name, last_name;
}
Creating JsonDeserializer like
public class PersonResponseDeserializer implements JsonDeserializer<Response> {
// Create a new gson to make the default parsing for response object
private final Gson gson = new Gson();
#Override
public Response deserialize(JsonElement json, Type typeOfT
, JsonDeserializationContext context) throws JsonParseException {
Response r = gson.fromJson(json, typeOfT);
// Remove all persons from R that have last name null
r.getPeople().removeAll(
r.getPeople().stream().filter( p -> p.getLast_name() == null )
.collect(Collectors.toSet())
);
return r;
}
}
could then be used like
Gson gson = new GsonBuilder()
.registerTypeAdapter(Response.class, new PersonResponseDeserializer())
.create();
Response r = gson.fromJson(s, Response.class);
So this is if it is required to be done at the parse time. Maybe it is otherwise better to loop the People after parsing and exclude Persons without last name then.

How Gson knows which json element is to use which Deserializer

I have the following json input. And know i am using Gson to parse.
{
“type”: “type1”,
“date”: “Tue, 16 May 2017 07:09:33 +0000”,
“body”:
{
“formatA_1”: “aaa”,
“formatA_2”: “bbbcccddd”
}
"other": "info"
}
public class Data {
private String type;
private Long date;
private Body body;
private String other;
...
}
As i want to convert the date to long, So i implement the custom DateDeserializer.
public class DateDeserializer implements JsonDeserializer<Long> {
#Override
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return DateConvertUtils.convertStringDatetoLong(json.getAsString(), DateConvertUtils.SERVER_DATE_FORMAT);
}
}
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Long.class, new DateDeserializer());
Gson gson = gsonBuilder.create();
Data data = gson.fromJson(json, Data.class);
This is working. But i wonder, how the Gson knows that only the "date" element needs to use the DateDeserializer? How it knows that other elements no need to use DateDeserializer?
If I put more other custom deserializers, how it would know which element is to use which deserializer?
Thanks a lot.
Gson uses the last added deserializer for given type and uses the deserializer for all cases. In your case, it will use your deserializer for any and all Longs

POJO arraylist to String

I'm using retrofit 2 and i defined some POJO to be able to parse my response from ws
public class mPojo
{
public List<mPojo2> field;
}
How can i get the field as a string ?
The answer that fits my needs:
Gson gson = new GsonBuilder().create();
String json = gson.toJson(mPojo.field.get(i));

Android JSON parsing with GSON crash: LinkedTreeMap cannot be cast to Object

I am trying to store a list of objects into SharedPreferences, so therefore am using Gson to convert the list of objects into JSON and back again. However, when I store then retrieve the list of objects and the ListView's adapter is applied to the new List, I get the following error:
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to appuccino.simplyscan.Objects.Folder
at appuccino.simplyscan.Extra.DocumentAdapter.getView(DocumentAdapter.java:117)
where the error points at this line in the list's adapter:
Folder folder = folderList.get(position);
When storing the object list, I am using the following:
//folderList is a List<Folder> folderList = new ArrayList<>();
folderList.add(0, newFolder);
Gson gson = new Gson();
String newFoldersJson = gson.toJson(folderList);
PrefManager.putString(PrefManager.FOLDER_JSON, newFoldersJson);
where the last line simply stores the string into SharedPreferences. When retrieving the list from SharedPreferences, I am using the following:
public static List<Folder> loadFolders(MainActivity main){
//JSON containing a list of folder objects
String foldersJSON = PrefManager.getString(PrefManager.FOLDER_JSON, "");
if(!foldersJSON.isEmpty()){
Gson gson = new Gson();
List<Folder> folderList = gson.fromJson(foldersJSON, List.class);
return folderList;
}
return new ArrayList<>();
}
If it helps, here is how my Folder class is defined:
public class Folder {
private String name;
private List<String> docNameList;
private transient List<Document> docList;
public Folder(String n) {
name = n;
docList = new ArrayList<>();
docNameList = new ArrayList<>();
}
}
Not a answer to your question, but a suggestion. I am also trying to work with json in Android recently and researched a lot about which one to use jackson or gson. Seems like there are 2 advantages of jackson:
Performance of jackson is better than gson.
If you are using the same on server side then you get consistency.
Ref:
[be-lazy-productive-android][1]
http://java.dzone.com/articles/be-lazy-productive-android

getting sub JSON values in an easy way in android

[{"a":
{"b":"c",
"d":"e",
"f":"g"}
{"a2":
{"b":"c2",
"d":"e2",
"f":"g2"}]
This is the JSON data I 'have to' use. Is there any easy way for me to reach, let's say the b values without having to go through a and a2?
Use GSON
You should create a class for that:
public class MyObject {
private A a;
private A a2;
// a and a2 getters here to check if it parses successfully
}
Class A
public class A {
private String b;
private String d;
private String f;
// getters
}
And somewhere where you want to parse:
Type listType = new TypeToken<ArrayList<MyObject >>() {}.getType();
Gson gson = new Gson();
List<MyObject> list = gson.fromJson(yourJsonStringHere, listType);

Categories

Resources