luoxianli / google-gson

Automatically exported from code.google.com/p/google-gson
0 stars 0 forks source link

Need field-specific information in custom JsonSerializer #306

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
In my use case, I need to truncate some long String to fit the need of mobile 
client while still keeping the full String for web.

So I built two separate Gson objects for web and mobile, and specify some 
annotation on String field which needs to be truncated:

class Foo {
  @MobileJsonTruncate(70)
  String message;
}

But in the custom JsonSerializer, I have little information about the field 
being serialized, thus I can't get the annotation to determine whether to 
truncate and how long to keep.

Ideally, if we have the FieldAttributes information as a parameter of 
serialize() method or stored within JsonSerializationContext, that will be a 
easy job.

But now, I have to write an ugly work around like this:

class MobileJsonSerializer implements ExclusionStrategy, JsonSerializer<String> 
{

    @Override
    public boolean shouldSkipField(final FieldAttributes aField) {
        iField = aField;
        return aField.getAnnotation(WebExclusive.class) != null;
    }

    @Override public JsonElement serialize(final String aSrc, final Type aTypeOfSrc, final JsonSerializationContext aContext) {
        final MobileTruncate annotation = iField.getAnnotation(MobileTruncate.class);
        if (annotation == null)
            return aContext.serialize(aSrc);
        final JsonPrimitive result = new JsonPrimitive(aSrc.substring(0, Math.min(aSrc.length(), annotation.value())));
        iField = null;
        return result;
    }

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

    private FieldAttributes iField;
}

Original issue reported on code.google.com by oasisfeng on 1 Apr 2011 at 1:34

GoogleCodeExporter commented 9 years ago
Issue 307 has been merged into this issue.

Original comment by joel.leitch@gmail.com on 13 Apr 2011 at 7:30

GoogleCodeExporter commented 9 years ago
Very clever workaround...hats off to you for thinking about it this way.

I believe this is a valid and useful feature request so I will look into 
getting this into the next release of Gson.

Side note:
Your above implementation is not Thread-safe.

Original comment by joel.leitch@gmail.com on 13 Apr 2011 at 7:34

GoogleCodeExporter commented 9 years ago
Yes, this workaround is not thread-safe, so I encapsulated the Gson instance 
within ThreadLocal to keep it safe for concurrency.

BTW, this workaround also rely on another internal assumption that 
shouldSkipField() was called before each serialize() call. But in my opinion, 
this assumption could become false if shouldSkipField() method is optimized to 
be called only once per field, but not per field of each instance.

Original comment by oasisfeng on 17 Apr 2011 at 4:34

GoogleCodeExporter commented 9 years ago

hi! I would like to second the request for enhancement. I've got a very similar 
use case where I would like to alter serialization / deserialization based on a 
filed's annotation.

Original comment by pkozlows...@gmail.com on 19 Dec 2011 at 8:09

GoogleCodeExporter commented 9 years ago
Can you use two different Gson instances, each of which has its own 
ExclusionStrategy?

Original comment by limpbizkit on 18 Mar 2012 at 8:22

GoogleCodeExporter commented 9 years ago
Is there any update? Will this be ever implemented?

Original comment by armond...@gmail.com on 7 May 2013 at 10:04