2016-09-09 3 views
0

Представьте, у меня есть два класса, MyClass и MyOtherClass. Я написал сериализатор для MyClass. Без него попытка сериализации MyOtherClass не будет работать (потому что MyClass не сериализуется без сериализатора, который я написал).Мои сериализаторы зависят друг от друга, как я могу гарантировать, что оба используются

package com.mycompany.javatest; 

import com.google.gson.*; 
import java.lang.reflect.*; 

public class JavaTest { 

    static class MyClass { 

     private int someValue = 123; 
    } 

    static class MyOtherClass { 

     private MyClass mc = new MyClass(); 
    } 

    static class MyClassSerializer implements JsonSerializer<MyClass> { 

     @Override 
     public JsonElement serialize(MyClass t, Type type, JsonSerializationContext jsc) { 

      JsonObject result = new JsonObject(); 
      // (Doing some magic to serialize the object here...) 
      result.add("someValue", jsc.serialize(t.someValue)); 
      return result; 

     } 
    } 

    static class MyOtherClassSerializer implements JsonSerializer<MyOtherClass> { 

     @Override 
     public JsonElement serialize(MyOtherClass t, Type type, JsonSerializationContext jsc) { 

      JsonObject result = new JsonObject(); 
      result.add("mc", jsc.serialize(t.mc)); // <--- Will fail if not using the MyClassSerializer 
      return result; 

     } 
    } 

    public static void main(String[] args) { 

     GsonBuilder gb = new GsonBuilder(); 
     gb.registerTypeAdapter(MyOtherClassSerializer.class, new MyOtherClassSerializer()); 
     Gson gson = gb.create(); 
     MyOtherClass object = new MyOtherClass(); 

     String json = gson.toJson(object, MyOtherClass.class); // <--- MyClassSerializer.serialize MUST be invoked, or this will fail 

    } 
} 

Мой вопрос, как я могу применять, что MyClassSerializer зарегистрирован когда MyOtherClassSerializer зарегистрирован? Очевидным ответом является просто зарегистрировать как адаптеры типа, но я хотел бы знать, есть ли способ принудительно зарегистрировать их при регистрации MyOtherClassSerializer. Один из вариантов - разрешить доступ к типам адаптеров только с помощью метода «register», но мне не нравится это решение. Я все еще хочу, чтобы MyClassSerializer был доступен.

public void registerMyOtherClassSerializer(GsonBuilder builder) { 

    builder.registerTypeAdapter(MyClass.class, new MyClassSerializer()); 
    builder.registerTypeAdapter(MyOtherClass.class, new MyOtherClassSerializer()); 

} 

Мысли?

+0

Вместо того чтобы обеспечить два отдельных 'ClassSerializer's, вы могли бы обеспечить единый' TypeAdapterFactory' (https://google.github.io/gson/apidocs/com/google /gson/TypeAdapterFactory.html) для ваших пользовательских классов –

ответ

0

Благодаря Томасу Клегеру. Это то, что я в конечном итоге делает:

package com.mycompany.javatest; 

import com.google.gson.*; 
import com.google.gson.reflect.*; 
import com.google.gson.stream.*; 
import java.io.*; 

public class JavaTest { 

    static class MyClass { 
     private final int someValue = 123; 
    } 

    static class MyOtherClass { 
     private final MyClass mc = new MyClass(); 
    } 

    public static void main(String[] args) { 

     GsonBuilder gb = new GsonBuilder(); 
     gb.registerTypeAdapterFactory(new MyTypeAdapterFactory()); 
     Gson gson = gb.create(); 
     MyOtherClass object = new MyOtherClass(); 

     String json = gson.toJson(object, MyOtherClass.class); 
     System.out.println(json); 

    } 

    static class MyTypeAdapterFactory implements TypeAdapterFactory { 

     @Override 
     public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> tt) { 

      if (MyClass.class.isAssignableFrom(tt.getRawType())) { 
       return (TypeAdapter<T>) new MyClassAdapter(); 
      } 

      return null; 
     } 

     private static class MyClassAdapter extends TypeAdapter<MyClass> { 

      @Override 
      public MyClass read(JsonReader reader) throws IOException { 
       throw new UnsupportedOperationException(); 
      } 

      @Override 
      public void write(JsonWriter writer, MyClass t) throws IOException { 
       writer.beginObject(); 
       writer.name("someValue"); 
       writer.value(t.someValue); // (Doing some magic to serialize the object here...) 
       writer.endObject(); 
      } 
     } 
    } 
} 
Смежные вопросы