Processing custom annotations for serialize and deserialize

3,332 views
Skip to first unread message

Craig LaSalle

unread,
Sep 24, 2012, 7:57:38 PM9/24/12
to googl...@googlegroups.com
Hi -

It looks like I can write adapters to do custom processing (serialize / deserialize) based on object type. It would be really nice to also do custom serialization / deserialization processing based on custom annotations.

Here's a sample of what I'd like to do:

BEGIN SNIPPET >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {
}

public class SampleEntity {
private String nameField;
@MyCustomAnnotation          // <<< THIS IS THE CUSTOM ANNOTATION
private String processField;
public SampleEntity(String f1, String f2) {
nameField = f1;
processField = f2;
}
public String getNameField() {
return nameField;
}
public void setNameField(String nameField) {
this.nameField = nameField;
}
public String getProcessField() {
return processField;
}
public void setProcessField(String processField) {
this.processField = processField;
}
}


// main fragment

{
    // create the gson object via the gson builder
    GsonBuilder gsonBuilder = new GsonBuilder();
    
    // ====> HERE'S THE NEW PART TO ALLOW PROCESSING CUSTOM ANNOTATIONS ON A FIELD <====
    gsonBuilder.registerAnnotationAdapter(MyCustomAnnotation.class, new MyCustomAnnotationAdapter());
    
    gson = gsonBuilder.create();
    
    String json = gson.toJson(new SampleEntity("foo1", "foo2");
    
    System.out.println("my json = " + json);

}


// custom annotation adapter class

public class MyCustomAnnotationAdapter implements JsonSerializer<MyCustomAnnotation>, JsonDeserializer<MyCustomAnnotation> {

// JsonSerializer and JsonDeserializer would need to provide access to the field information for adapter to work

    @Override
    public JsonElement serialize(SecureId src, Type typeOfSrc, JsonSerializationContext context) {
        // todo ...
    }

    @Override
    public SecureId deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
        // todo ...
    }
}

<<<<<<<<<<<<<<<<<<<<<<<<<< END SNIPPET


The idea is to be able to provide custom serialization and deserialization on a field level based on a custom annotation on that field. If this is already possible, it would be great to get a pointer to the documentation or a code snippet.

Thanks!
-Craig LaSalle

Inderjeet Singh

unread,
Sep 24, 2012, 8:12:59 PM9/24/12
to googl...@googlegroups.com
In serialize and deserialize methods of JsonSerializer/JsonDeserializer, you have the Type available to you already.
You can get the fields and their annotations via standard reflection. Have you tried that?

There is a low priority outstanding bug on Gson about providing custom actions on arbitrary annotations:
However, we haven't had a good concrete proposal on what the behavior should be.

Inder
----

Craig LaSalle

unread,
Sep 24, 2012, 8:30:50 PM9/24/12
to googl...@googlegroups.com
Thanks for the quick response!

I did try that, and from what I could tell, I can indeed look at the fields within the type (class) that gets passed in, but I cannot get access to the field for which that type is defined. As a result, the solution seems kind of clunky.

For example:

class A {
    String f1;
    String f2;
    ...
    @CustomAnnotation
    String f20;

}

To handle this processing I have to write a custom type adapter for class A, and in the processor I have to iterate through all the fields and annotations myself, outputting the JSON for each and processing the annotations as found. But, it would be nice if my custom annotation adapter only got called by the gson framework when the field for "String f20" with the @CustomAnnotation was being serialized / deserialized. Otherwise, it feels like I'm coding a mini sub-parser.

An alternative approach I tried was to wrap "String f20" in a special wrapper class, then I can code a type adapter for that wrapper class. This, however, makes the code awkward, if I have to wrap a many Strings, each in its own wrapper class.

I hope this makes sense, and I hope I'm understanding the gson processing correctly.

How do I go about submitting a concrete proposal for this?

Thanks!
-Craig LaSalle

Inderjeet Singh

unread,
Sep 25, 2012, 4:32:37 AM9/25/12
to googl...@googlegroups.com
We are looking at providing a solution to http://code.google.com/p/google-gson/issues/detail?id=269 in our next major release, so you should share your proposal there. Concrete proposals are great!

Thanks
Inder
----

Craig LaSalle

unread,
Sep 25, 2012, 6:25:54 PM9/25/12
to googl...@googlegroups.com
It looks like the thread you reference is pretty much the same request as mine. I'll try to cook up something concrete.

Thanks,
-Craig

Maaartin

unread,
Sep 25, 2012, 11:08:31 PM9/25/12
to googl...@googlegroups.com
For me the important part here is to allow custom processing of only a part of an object, while letting gson process the remaining fields in the usual way. It could simplify quite a few things, and recently I saw such a request in

While using an annotation is quite natural here, I could also imagine something like

interface FieldAdapterFactory {
<T> TypeAdapter<T> create(Gson gson, TypeToken<T> type, Field field);
}

where the user could examine the `field` for its name, parent class, annotations, or whatever. Unlike annotations it also applies to third party classes.

Reply all
Reply to author
Forward
0 new messages