question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Document GSON serializer

See original GitHub issue

I have a RealmObject like this :

public class Konsumen extends RealmObject {
    @SerializedName("id_konsumen") @PrimaryKey private String idKonsumen;
    @SerializedName("nama_konsumen") private String namaKonsumen;
    private String telepon;
    private String alamat;
    private String kota;
    private String keterangan;
    private boolean modified;
    private int deleted;

    public Konsumen() {}

    // Getter and setter...
}

When I tried to send the object to my server using Retrofit, it failed with error like this :

05-15 20:09:32.423  19331-19596/com.yulia.admin D/WEB-SERVICE﹕ ---> HTTP POST http://yulia-radhi.rhcloud.com/api/konsumen
05-15 20:09:32.423  19331-19596/com.yulia.admin D/WEB-SERVICE﹕ Content-Type: application/json; charset=UTF-8
05-15 20:09:32.423  19331-19596/com.yulia.admin D/WEB-SERVICE﹕ Content-Length: 32
05-15 20:09:32.423  19331-19596/com.yulia.admin D/WEB-SERVICE﹕ [{"modified":false,"deleted":0}]
05-15 20:09:32.423  19331-19596/com.yulia.admin D/WEB-SERVICE﹕ ---> END HTTP (32-byte body)
05-15 20:09:33.123  19331-19596/com.yulia.admin D/WEB-SERVICE﹕ <--- HTTP 500 http://yulia-radhi.rhcloud.com/api/konsumen (696ms)
05-15 20:09:33.123  19331-19596/com.yulia.admin D/WEB-SERVICE﹕ : HTTP/1.1 500 Internal Server Error

From this logcat, I found out that the error is happened because GSON unable to convert the object Konsumen.java entirely, and only able to convert field modified and deleted into JSON. Thats why when Retrofit send this JSON to my server, it caused Internal Server Error, because my server need at least the idKonsumen and namaKonsumen.

After looking around, I’ve found a StackOverflow question with same problem. There it said to convert RealmObject to JSON I have to create my own serializer. So, I create a KonsumenSerializer like this :

public class KonsumenSerializer implements JsonSerializer<Konsumen> {
    @Override
    public JsonElement serialize(Konsumen src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject object = new JsonObject();
        object.addProperty("id_konsumen", src.getIdKonsumen());
        object.addProperty("nama_konsumen", src.getNamaKonsumen());
        object.addProperty("telepon", src.getTelepon());
        object.addProperty("alamat", src.getAlamat());
        object.addProperty("kota", src.getKota());
        object.addProperty("keterangan", src.getKeterangan());
        object.addProperty("deleted", src.getDeleted());
        return object;
    }
}

After that, I register my serializer in my RestClient :

public class RestClient {
    private static final String API_URL = "http://yulia-radhi.rhcloud.com";

    public static ApiService getService() {
        ExclusionStrategy exclusionStrategy = new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                return f.getDeclaringClass().equals(RealmObject.class);
            }

            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                return false;
            }
        };

        Gson gson = new GsonBuilder()
                .setExclusionStrategies(exclusionStrategy)
                .registerTypeAdapter(Konsumen.class, new KonsumenSerializer())
                .create();

        return new RestAdapter.Builder()
                .setEndpoint(API_URL)
                .setConverter(new GsonConverter(gson))
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setLog(new AndroidLog("WEB-SERVICE"))
                .build()
                .create(ApiService.class);
    }
}

After that, I tried again to send Konsumen data to server using Retrofit, but it still failed with similar error like before.

So, my question is, how can I convert the RealmObject into JSON properly ?

On issue #812, mpost said :

Creating a normal JsonSerializer and registering it as a type adapter is not straight forward. Since you are actually working against the Proxy object, gson tries to match the adapter against the proxy which is not found. So you either register the serializer against the proxy or you use a different library.

If so, how can I do that, because I can’t find the proxy class for my Konsumen object.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:22 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
RadhiFadlillahcommented, May 17, 2015

Nevermind guys, it works. My internet connection was unstable, that’s why it failed when connecting to server.

Conclusion

To convert RealmObject into JSON using Gson library, we have to create our own Serializer and register it to the proxy class of our model, NOT to the model itself. So, for my Konsumen model, I have to register my KonsumenSerializer to proxy class io.realm.KonsumenRealmProxy. I hope in near future Realm will support converting RealmObject to JSON internally, so we don’t have to create ourr custom serializer.

My Final Code

Model Konsumen :



public class Konsumen extends RealmObject {
    @SerializedName("id_konsumen") @PrimaryKey private String idKonsumen;
    @SerializedName("nama_konsumen") private String namaKonsumen;
    private String telepon;
    private String alamat;
    private String kota;
    private String keterangan;
    private boolean modified;
    private int deleted;

    public Konsumen() {}

    // Getter and setter...
}

Serializer for my Konsumen :

public class KonsumenSerializer implements JsonSerializer<Konsumen> {
    @Override
    public JsonElement serialize(Konsumen src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject object = new JsonObject();
        object.addProperty("id_konsumen", src.getIdKonsumen());
        object.addProperty("nama_konsumen", src.getNamaKonsumen());
        object.addProperty("telepon", src.getTelepon());
        object.addProperty("alamat", src.getAlamat());
        object.addProperty("kota", src.getKota());
        object.addProperty("keterangan", src.getKeterangan());
        object.addProperty("deleted", src.getDeleted());
        return object;
    }
}

And last, my RestClient :

public class RestClient {
    private static final String API_URL = "http://yulia-radhi.rhcloud.com";

    public static ApiService getService() {
        // Create Gson builder
        GsonBuilder gsonBuilder = new GsonBuilder();

        gsonBuilder.setExclusionStrategies(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                return f.getDeclaringClass().equals(RealmObject.class);
            }

            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                return false;
            }
        });

        // Register adapter to builder
        try {
            gsonBuilder.registerTypeAdapter(Class.forName("io.realm.KonsumenRealmProxy"), new KonsumenSerializer());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        // Create gson
        Gson gson = gsonBuilder.create();

        // Set Gson as converter for Retrofit
        return new RestAdapter.Builder()
                .setEndpoint(API_URL)
                .setConverter(new GsonConverter(gson))
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .setLog(new AndroidLog("WEB-SERVICE"))
                .build()
                .create(ApiService.class);
    }
}
1reaction
AnixPasBesoincommented, Jan 18, 2017

@Zhuinden Thanx a lot for your enlightenment!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Gson User Guide - Google Sites
Serializing and Deserializing Collection with Objects of Arbitrary Types. You can serialize the collection with Gson without doing anything specific: toJson( ...
Read more >
Gson (Gson 2.8.0 API) - Javadoc.io
Gson provides default serialization and deserialization for Enums, Map , URL , URI , Locale , Date , BigDecimal , and BigInteger classes....
Read more >
Gson - Object Serialization - Tutorialspoint
Gson - Object Serialization, Let's serialize a Java object to a Json file and then read that Json file to get the object...
Read more >
Java Gson - JSON serialization and deserialization ... - ZetCode
Gson is a Java serialization/deserialization library to convert Java Objects into JSON and back. Gson was created by Google for internal use ...
Read more >
google/gson: A Java serialization/deserialization ... - GitHub
A Java serialization/deserialization library to convert Java Objects into JSON ... document: This document discusses issues we faced while designing Gson.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found