java – Gson反序列化其Class实现的接口

前端之家收集整理的这篇文章主要介绍了java – Gson反序列化其Class实现的接口前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用Retrofit 2.1.0和converter-gson:2.1.0以及单独使用gson:2.6.2来自定义序列化/反序列化.问题是我的POJO应隐藏在接口后面,我想告诉gson哪个类应该是反序列化的接口.并且在反序列化/序列化后,改进应该能够返回接口.如果我可以利用泛型并轻松创建一种方法来告诉Gson或Retrofit将FooInterface序列化/反序列化为FooClass,那将是一件好事.

解决方法

我假设您要为所有接口及其各自的实现创建单个反序列化器.请按以下步骤操作:

1.创建一个将由其他应用程序界面扩展的基本界面.需要为所有接口和实现类创建单个反序列化器.

  1. public interface Convertable {
  2. String getClassName();
  3. }@H_403_9@
  4. 2.创建功能界面和实现类.例如,让我们将它们命名为FooInterfaceFooClass. FooInterface应该扩展Convertable接口.

  5. FooInterface

  6. public interface FooInterface extends Convertable {
  7. }@H_403_9@ 
  8.  

    FooClass

  9.   
  10.  
    public class FooClass implements FooInterface {
  11.     // DISCRIMINATOR FIELD
  12.     private final String className;
  13.     private String field1;
  14.     private String field2;
  15.     public FooClass() {
  16.         this.className = getClass().getName();
  17.     }
  18.     public String getClassName() {
  19.         return className;
  20.     }
  21.     public String getField1() {
  22.         return field1;
  23.     }
  24.     public void setField1(String field1) {
  25.         this.field1 = field1;
  26.     }
  27.     public String getField2() {
  28.         return field2;
  29.     }
  30.     public void setField2(String field2) {
  31.         this.field2 = field2;
  32.     }
  33. }@H_403_9@ 
  34.  

    请注意,getClassName()返回的值用作将在Gson反序列化器(下一步)中用于初始化可返回实例的鉴别器字段.我假设您的序列化程序和反序列化程序类将驻留在同一个程序包中,即使它们位于不同的客户端和服务器应用程序中.如果没有,那么您将需要更改getClassInstance()实现,但这样做非常简单.

  35.  

    3.为您的所有应用程序实现自定义Gson Serializer

  36.   
  37.  
    import com.google.gson.JsonDeserializationContext;
  38. import com.google.gson.JsonDeserializer;
  39. import com.google.gson.JsonElement;
  40. import com.google.gson.JsonObject;
  41. import com.google.gson.JsonParseException;
  42. import com.google.gson.JsonPrimitive;
  43. public class ConvertableDeserializer<T extends Convertable> implements JsonDeserializer<T> {
  44.     private static final String CLASSNAME = "className";
  45.     public T deserialize(final JsonElement jsonElement,final Type type,final JsonDeserializationContext deserializationContext
  46.                         ) throws JsonParseException {
  47.         final JsonObject jsonObject = jsonElement.getAsJsonObject();
  48.         final JsonPrimitive prim = (JsonPrimitive) jsonObject.get(CLASSNAME);
  49.         final String className = prim.getAsString();
  50.         final Class<T> clazz = getClassInstance(className);
  51.         return deserializationContext.deserialize(jsonObject,clazz);
  52.     }
  53.     @SuppressWarnings("unchecked")
  54.     public Class<T> getClassInstance(String className) {
  55.         try {
  56.             return (Class<T>) Class.forName(className);
  57.         } catch (ClassNotFoundException cnfe) {
  58.             throw new JsonParseException(cnfe.getMessage());
  59.         }
  60.     }
  61. }@H_403_9@ 
  62.  

    4.使用Gson注册Deserializer并初始化改造

  63.   
  64.  
    private static GsonConverterFactory buildGsonConverter() {
  65.         final GsonBuilder builder = new GsonBuilder();
  66.         // Adding custom deserializers
  67.         builder.registerTypeAdapter(FooInterface.class,new ConvertableDeserializer<FooInterface>());
  68.         final Gson gson = builder.create();
  69.         return GsonConverterFactory.create(myGson);
  70.     }
  71.     public void initRetrofit() {
  72.         Retrofit retrofit = new Retrofit.Builder()
  73.                 .baseUrl("REST_ENDPOINT")
  74.                 .addConverterFactory(buildGsonConverter())
  75.                 .client(httpClient)
  76.                 .build();
  77.     }@H_403_9@ 
  78.  

    如果需要,您可以为所有实现注册适配器,使用:

  79.   
  80.  
    builder.registerTypeAdapter(Convertable.class,new ConvertableDeserializer<Convertable>());@H_403_9@

猜你在找的Java相关文章