Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
360 views
in Technique[技术] by (71.8m points)

java - Deserializing ImmutableList using Gson

I'm using quite a few immutable collections and I'm curious how to deserialize them using Gson. As nobody answered and I've found the solution myself, I'm simplifying the question and presenting my own answer.

I had two problems:

  • How to write a single Deserializer working for all ImmutableList<XXX>?
  • How to register it for all ImmutableList<XXX>?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Update: There's https://github.com/acebaggins/gson-serializers which covers many guava collections:

  • ImmutableList
  • ImmutableSet
  • ImmutableSortedSet
  • ImmutableMap
  • ImmutableSortedMap

How to write a single Deserializer working for all ImmutableList?

The idea is simple, transform the passed Type representing an ImmutableList<T> into a Type representing List<T>, use the build-in Gson's capability to create a List and convert it to an ImmutableList.

class MyJsonDeserializer implements JsonDeserializer<ImmutableList<?>> {
    @Override
    public ImmutableList<?> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
        final Type type2 = ParameterizedTypeImpl.make(List.class, ((ParameterizedType) type).getActualTypeArguments(), null);
        final List<?> list = context.deserialize(json, type2);
        return ImmutableList.copyOf(list);
    }
}

There are multiple ParameterizedTypeImpl classes in Java libraries I use, but none of them intended for public usage. I tested it with sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.

How to register it for all ImmutableList?

That part is trivial, the first argument to register is java.lang.reflect.Type which mislead me to using ParameterizedType, where simply using Class does the job:

final Gson gson = new GsonBuilder()
    .registerTypeAdapter(ImmutableList.class, myJsonDeserializer)
    .create();

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...