2013-08-25 14 views
7

注釈を使用してシリアル化形式を制御しようとしています。しかし、TypeAdapterまたはTypeAdapterFactoryの内部からフィールドアノテーションにアクセスする方法はないようです。注釈によるGSONコントロールのシリアル化書式設定

ここに私が達成しようとしているものの例があります。 Movieオブジェクトについては

import org.joda.time.DateTime; 

public class Movie { 
    String title; 

    @DateTimeFormat("E, M d yyyy") 
    DateTime releaseDate; 
    // other fields ... 
} 

public class LogEvent { 
    String message; 

    @DateTimeFormat("yyyyMMdd'T'HHmmss.SSSZ") 
    DateTime timestamp; 
} 

、私は "2013年8月24日(土曜日)" としてではなく、のLogEvent、 "20130824T103025.123Z" の日付をシリアル化します。

私は

TIA(私たちは、異なるフォーマットを必要とし、その中のDateTimeフィールドに100の別のクラスを持っている場合を想像)、クラスごとに別々のTypeAdapterFactory年代を記述することなく、これをやろうとしています!

答えて

1

ここには方法があります。アイデアはTypeAdapterFactoryを使用してクラスを読み込むことです。次に、オブジェクトがロードされた後、タイプDateTimeのフィールドを検出して注釈を適用し、値を置き換えます。

どのようにDateTimeオブジェクトが格納されるのかわからないので、getAsJsonPrimitiveの代わりにgetAsJsonObjectを使用する必要があります。

final class MyAdapter implements TypeAdapterFactory { 
    @Override 
    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> tokenType) { 
    final TypeAdapter<T> adapter = gson.getDelegateAdapter(this, tokenType); 

    return new TypeAdapter<T>() { 
     @Override 
     public T read(JsonReader reader) throws IOException { 
     JsonElement tree = gson.getAdapter(JsonElement.class).read(reader); 
     T out = adapter.fromJsonTree(tree); 

     // important stuff here 
     Class<? super T> cls = tokenType.getRawType(); 
     for (Field field : cls.getDeclaredFields()) { 
      if (DateTime.class.isAssignableFrom(field.getType())) { 
      DateTimeFormat ano = field.getAnnotation(DateTimeFormat.class); 
      if (ano != null) { 
       JsonPrimitive val = ((JsonObject) tree).getAsJsonPrimitive(field.getName()); 
       String format = ano.value(); 

       DateTime date = // .. do your format here 
       field.set(out, date); 
      } 
      } 
     } 

     return out; 
     } 

     @Override 
     public void write(JsonWriter writer, T value) throws IOException { 
     } 
    }; 
    } 
} 
+0

私が避けようとしているのは、各クラスでフィールドの書式を異なるようにしたいだけなので、DateTimeフィールドを含むクラスごとにカスタムアダプタを作成する必要があるということです。 ReflectiveTypeAdapterFactoryを再実装しなければ、これは可能ではないかもしれません。 – hendysg

+0

これは、特定のアダプタではなく、 'TypeAdapterFactory'です。したがって、すべてのクラスで動作するはずです。ちょうど試して。 – PomPom

関連する問題