Custom serialization for JUST specific fields

4,833 views
Skip to first unread message

Aleem Mawani

unread,
Sep 17, 2012, 1:43:36 AM9/17/12
to googl...@googlegroups.com
Hi there,

I have a specific field in one of my POJO's that I'd like to do custom serialization, however, I'd like the rest of the object to be serialized in the default manner. For example, say I have the following:

public class Foo {
String field1;
String field2;
.
.
String field100
Object customField;
}

I'd like to write a serializer such that all of Foo is serialized in the default manner, except for "customField" which i want to do the serialization manually. Notice that customField is of type Object and I don't want to custom serialize all fields of type Object in all my classes - just this one field in Foo. Is this possible?

Brandon Mintern

unread,
Sep 17, 2012, 12:36:48 PM9/17/12
to googl...@googlegroups.com
This is the simplest thing that I can come up with:

Create a deserializer:

1. FooSerializer implements JsonSerializer<Foo>. You'll need to implement:
public JsonElement serialize(Foo foo, Type fooType,
JsonSerializationContext jsc)

2. Register the serializer with your main Gson instance (let's call it gson).

3. In your serializer, declare the following:
private static final Gson gsonWithoutFooSerializer = new Gson();

4. Make customField transient:
transient Object customField

5. When you call gson.toJson(foo), your serialize method will be called.

6. In the implementation of that method, you'll do something like:

JsonElement json = gsonWithoutFooSerializer.toJsonTree(foo);
JsonElement customFieldJson = ... // whatever special logic you want
json.getAsJsonObject().add("customField", customFieldJson);
return json;

Does that make sense? You need a custom serializer, but in the
implementation you can use an independent Gson instance to do most of
the work for you. By default, Gson does not serialize transient
fields. After the serialization, you can add your customField manually
with whatever logic you wish.
> --
> You received this message because you are subscribed to the Google Groups
> "google-gson" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-gson/-/SESkDfr54UwJ.
> To post to this group, send email to googl...@googlegroups.com.
> To unsubscribe from this group, send email to
> google-gson...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/google-gson?hl=en.

Brandon Mintern

unread,
Sep 17, 2012, 12:37:20 PM9/17/12
to googl...@googlegroups.com
Oops...

On Mon, Sep 17, 2012 at 9:36 AM, Brandon Mintern <min...@easyesi.com> wrote:
> This is the simplest thing that I can come up with:
>
> Create a deserializer:

^^ That should have said "Create a serializer"

Aleem Mawani

unread,
Sep 17, 2012, 12:57:53 PM9/17/12
to googl...@googlegroups.com
Thanks - that is very helpful. Trying now... but does this mean I'll also have to write a custom deserializer? I'd like to just use the default behavior but when creating my own type adapter I have to implement both write AND read. 

Does it make sense to use a type adapter factory and then use the delegate pattern?

Aleem Mawani

unread,
Sep 17, 2012, 1:00:54 PM9/17/12
to googl...@googlegroups.com
Just reread your solution and you are suggesting using the JsonSerializer interface and not TypeAdapter which makes sense. However, I'd like it to be as performant as possible, any way to do this using a TypeAdapter?

Brandon Mintern

unread,
Sep 17, 2012, 1:33:07 PM9/17/12
to googl...@googlegroups.com
Yes, TypeAdapter is more performant and is typically the better
solution, but that will make delegation more difficult. That is, the
underlying Gson instance that you use would do
jsonWriter.beginObject(), [write some fields], jsonWriter.endObject().
This means that you won't be able to arbitrarily insert your own
field->Json mappings into the resulting object as you can with my
approach. As with many decisions in programming, it's a tradeoff
between programmer time and performance.

As for your deserialization question, whatever special logic you use
to serialize customField will need to be performed in reverse to set
the value on deserialization. If you don't mind the less performant
approach, you can use JsonDeserializer, remove the custom field from
the json that you receive, delegate to the internal Gson instance, and
then set customField manually.

If you want to use the TypeAdapter, I can't come up with a good way to
delegate to an internal Gson in this case. You'd just have to do the
whole de/serialization yourself, which seemed to be what you were
trying to avoid.

In regards to the TypeAdapterFactory question, you really shouldn't
have to use a factory unless you're doing really reflective,
high-level things. Most of the time, you can just create the
JsonDeserializer, JsonSerializer, and TypeAdapter instances that you
need and register each one mapped to its appropriate class.
> --
> You received this message because you are subscribed to the Google Groups
> "google-gson" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/google-gson/-/Q_gMVCU9ly0J.

Inderjeet Singh

unread,
Sep 17, 2012, 2:39:27 PM9/17/12
to googl...@googlegroups.com
If you want to use TypeAdapter, you can write it as a TypeAdapterFactory. With that you would have the Gson instance available for serialization and deserialization. In fact, you can call Gson.getDelegateAdapter(this, currentType) and invoke the default type adapter on the current instance. This saves you from serializing/deserializing each field separately.

Inder

Aleem Mawani

unread,
Sep 17, 2012, 2:45:40 PM9/17/12
to googl...@googlegroups.com
Sorry can you explain a little more - for example if I have a TypeAdapterFactory that creates type adapters for Foo, and also has the delegate adapter for Foo, how would you modify what the delegate adapter outputs so that customField gets some customTreatment?

To view this discussion on the web visit https://groups.google.com/d/msg/google-gson/-/ZUw5rPwfcqoJ.

Craig LaSalle

unread,
Sep 25, 2012, 11:39:12 PM9/25/12
to googl...@googlegroups.com
There was another thread to address this type of issue using custom annotations that could be processed during the serialization / desrialization process.

Reply all
Reply to author
Forward
0 new messages