Gson: Apply serialize nulls for specific classes only

Created on 26 Aug 2016  路  3Comments  路  Source: google/gson

I want a Gson setup in which nulls are not serialized by default. I want nulls to be serialized for certain class only. This is how I tried to solve it, but it does not work as expected.

This is how a gson instance is created, used for general serialization/deserialization for all API requests app needs to make:

 @Provides
 Gson provideGson() {
        GsonBuilder builder = new GsonBuilder()
                .registerTypeAdapter(SubmitBody.class, new SubmitBodySerializer();
        return builder.create();
    }

I want to make SubmitBody class an exception for serialization, I want null fields from this class to be serialized as Json nulls, unlike rest of the classes where such fields will be ignored. That's why I registered a custom serializer for this class that looks like this:

public class SubmitBodySerializer implements JsonSerializer<SubmitBody> {

    public SubmitBodySerializer(Gson gson) {
        this.gson = new GsonBuilder().serializeNulls().create();
    }

    @Override
    public JsonElement serialize(SubmitBody src, Type typeOfSrc, JsonSerializationContext context) {
        return gson.toJsonTree(src);
    }
}

Within this class I use a separate Gson instance which serializes nulls. I can see that serialize method returns correct JsonElement with serialized nulls, however, when I check the Json body sent to the API, nulls are nowhere to be found, as if they are ignored.

Most helpful comment

You can make a TypeAdapterFactory for your type (Foo) that wants to serialize nulls.

final class FooTypeAdapter extends TypeAdapter<Foo> {
  static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
    @SuppressWarnings("unchecked")
    @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
      if (type.getRawType() != Foo.class) {
        return null;
      }
      TypeAdapter<Foo> delegate = (TypeAdapter<Foo>) gson.getDelegateAdapter(this, type);
      return (TypeAdapter<T>) new FooTypeAdapter(delegate);
    }
  };

  private final TypeAdapter<Foo> delegate;

  FooTypeAdapter(TypeAdapter<Foo> delegate) {
    this.delegate = delegate;
  }

  @Override public void write(JsonWriter out, Foo value) throws IOException {
    boolean serializeNulls = out.getSerializeNulls();
    out.setSerializeNulls(true);
    try {
      delegate.write(out, value);
    } finally {
      out.setSerializeNulls(serializeNulls);
    }
  }

  @Override public Foo read(JsonReader in) throws IOException {
    return delegate.read(in);
  }
}

All 3 comments

I have exactly the same problem, does anyone have a solution to this yet?

You can make a TypeAdapterFactory for your type (Foo) that wants to serialize nulls.

final class FooTypeAdapter extends TypeAdapter<Foo> {
  static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
    @SuppressWarnings("unchecked")
    @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
      if (type.getRawType() != Foo.class) {
        return null;
      }
      TypeAdapter<Foo> delegate = (TypeAdapter<Foo>) gson.getDelegateAdapter(this, type);
      return (TypeAdapter<T>) new FooTypeAdapter(delegate);
    }
  };

  private final TypeAdapter<Foo> delegate;

  FooTypeAdapter(TypeAdapter<Foo> delegate) {
    this.delegate = delegate;
  }

  @Override public void write(JsonWriter out, Foo value) throws IOException {
    boolean serializeNulls = out.getSerializeNulls();
    out.setSerializeNulls(true);
    try {
      delegate.write(out, value);
    } finally {
      out.setSerializeNulls(serializeNulls);
    }
  }

  @Override public Foo read(JsonReader in) throws IOException {
    return delegate.read(in);
  }
}

Just a comment: when one wants to use it, this is the way:

private GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapterFactory(FooTypeAdapter.FACTORY);

Was this page helpful?
0 / 5 - 0 ratings

Related issues

danieleguiducci picture danieleguiducci  路  34Comments

GoogleCodeExporter picture GoogleCodeExporter  路  17Comments

GoogleCodeExporter picture GoogleCodeExporter  路  20Comments

LucianWang picture LucianWang  路  42Comments

GoogleCodeExporter picture GoogleCodeExporter  路  31Comments