2016-09-09 4 views
0

私は2つのクラス、MyClassMyOtherClassがあるとします。私は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 

    } 
} 

私の質問は、私はMyOtherClassSerializerが登録されている場合MyClassSerializerが登録されていることを強制する方法、ありますか?明らかな答えは、の両方のタイプのアダプタを登録することですが、MyOtherClassSerializerの登録時に両方を登録する方法があるかどうかを知りたいと思います。 1つのオプションは、このような "register"メソッドによって型アダプタにアクセスできるようにすることですが、私はこの解決策が嫌いです。私はまだMyClassSerializerにアクセスしたいです。

public void registerMyOtherClassSerializer(GsonBuilder builder) { 

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

} 

考えられますか?

+0

代わりに2つの別々の' ClassSerializer'sを提供する:これは私がやってしまったものです/gson/TypeAdapterFactory.html)カスタムクラス用 –

答えて

0

ThomasKlägerに感謝します。 、あなたは、単一の `TypeAdapterFactory`(https://google.github.io/gson/apidocs/com/googleを提供することができ

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(); 
      } 
     } 
    } 
} 
関連する問題