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;
        }
    });

Tags:

Java

Json

Gson