Gson: parameter get serialised even though it has @Expose(serialize = false)
Thanks to @peitek for pointing out that @Expose
is ignored unless .excludeFieldsWithoutExposeAnnotation()
is added to the GsonBuilder()
. However, I choose not to go with this route as it would require me to add @Expose
to every single parameter of my model classes just to ignore one field on serialisation. Instead I wrote a ExclusionStrategy
that checks for the presence of a custom SkipSerialisation
annotation on the parameter. I implemented these as follows:
The full GsonBuilder
with the strategy:
public static final Gson PRETTY_PRINT_JSON = new GsonBuilder()
.addSerializationExclusionStrategy(new ExclusionStrategy()
{
@Override
public boolean shouldSkipField(FieldAttributes f)
{
return f.getAnnotation(SkipSerialisation.class) != null;
}
@Override
public boolean shouldSkipClass(Class<?> clazz)
{
return false;
}
})
.setPrettyPrinting()
.create();
And the annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface SkipSerialisation
{
}
Now I can just do
@SkipSerialisation
@SerializedName("_id")
private String id;
and it works!
As you mentioned in your comments, @Expose
should be the better choice over transient
here. It's important to note that the default Gson instance does not regard the @Expose
annotation! It'll simply ignore it, no matter what you set as option.
If you want to activate the @Expose
options, you need to customize Gson. Based on your code above, change it to:
public static final Gson PRETTY_PRINT_JSON = new GsonBuilder()
.setPrettyPrinting()
.excludeFieldsWithoutExposeAnnotation();
.create();
Your @Expose(serialize = false)
should be active and excluded during serialization.
I just wanted to add here that you could use Expose in the desired way like this:
builder.addSerializationExclusionStrategy(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
Expose annotation = f.getAnnotation(Expose.class);
if(annotation != null)
return !annotation.serialize();
else
return false;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
Expose annotation = clazz.getAnnotation(Expose.class);
if(annotation != null)
return !annotation.serialize();
else
return false;
}
});
builder.addDeserializationExclusionStrategy(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
Expose annotation = f.getAnnotation(Expose.class);
if(annotation != null)
return !annotation.deserialize();
else
return false;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
Expose annotation = clazz.getAnnotation(Expose.class);
if(annotation != null)
return !annotation.deserialize();
else
return false;
}
});