2013-08-25 47 views
7

我想要使用註釋控制序列化格式。但似乎沒有任何方法可以從TypeAdapter或TypeAdapterFactory中訪問字段註釋。通過註釋GSON控制序列化格式化

下面是我試圖實現的一個例子。

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」。

我試圖做到這一點,而無需編寫單獨的TypeAdapterFactory的每個類(試想一下,如果我們有一個日期時間欄100個不同類的人身上,需要不同的格式)

TIA!

回答

1

這是一種方法。這個想法是使用TypeAdapterFactory加載你的類。然後在加載對象後,檢測DateTime類型的字段以應用註釋並替換該值。

在不知道如何存儲DateTime對象,因此可能需要使用getAsJsonObject而不是getAsJsonPrimitive

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