Uso mais simples do TypeAdapterFactory

AFAIK a customização gson mais flexível é possível via TypeAdapterFactory , porém pode ser desnecessariamente complicada. Isso me obriga a escrever para cada class manipulada, read e write , enquanto, às vezes, apenas um método é realmente necessário. Além disso, às vezes um JsonSerializer e / ou JsonDeserializer eram muito mais fáceis de escrever, por exemplo, como aqui . Isso me leva a estas perguntas:

  • É possível escrever um TypeAdapter que simplesmente delega um dos seus methods (por exemplo, escrevendo de ImmutableList para a escrita de List )?
  • É possível de alguma forma usar JsonSerializer e / ou JsonDeserializer juntamente com o TypeAdapterFactory ? Alternativamente, existe uma fábrica para eles?

É possível criar um TypeAdapter que delega um dos seus methods. Este caso de uso é uma parte importante da API e existe um método getDelegateAdapter () para esse propósito. Passe this como o primeiro argumento para getDelegateAdapter que retornará o adaptador que tem precedência após a fábrica atual.

 TypeAdapterFactory immutableListFactory = new TypeAdapterFactory() { @Override public  TypeAdapter create(Gson gson, TypeToken type) { if (!(type.getType() instanceof ParameterizedType) || !type.getRawType().equals(ImmutableList.class)) { return null; } ParameterizedType parameterizedType = (ParameterizedType) type.getType(); TypeAdapter delegate = gson.getDelegateAdapter(this, type); TypeAdapter elementAdapter = gson.getAdapter( TypeToken.get(parameterizedType.getActualTypeArguments()[0])); return new ImmutableListAdapter(delegate, elementAdapter); } class ImmutableListAdapter extends TypeAdapter> { private TypeAdapter> delegate; private TypeAdapter element; ImmutableListAdapter(TypeAdapter> delegate, TypeAdapter element) { this.delegate = delegate; this.element = element; } @Override public void write(JsonWriter out, ImmutableList value) throws IOException { delegate.write(out, value); } @Override public ImmutableList read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; } ImmutableList.Builder builder = ImmutableList.builder(); in.beginArray(); while (in.hasNext()) { builder.add(element.read(in)); } in.endArray(); return builder.build(); } } }; 

Você pode misturar e combinar o JsonSerializer / JsonDeserializer com o TypeAdapterFactory , mas não diretamente. A maneira mais simples é entrar em contato com o Gson para serializar valores filhos em sua class. Neste exemplo, alteramos o loop interno para isso:

  while (in.hasNext()) { builder.add(gson.fromJson(in, elementType)); } 

A principal diferença entre o JsonSerializer / JsonDeserializer e o TypeAdapter é o número de estágios necessários para ir do JSON ao seu modelo de object. Com o JsonSerializer / JsonDeserializer objects são primeiro convertidos no modelo DOM do Gson ( JsonElement etc.) e, em seguida, convertidos em seu modelo de object. Com TypeAdapter , a etapa intermediária é ignorada.

Isso torna o código do adaptador de tipo um pouco mais complicado de ler e escrever, portanto, você deve preferir apenas o código otimizado.

Intereting Posts