GSON通过注释控制序列化格式化

时间:2013-08-25 00:50:39

标签: java json gson

我正在尝试使用注释来控制序列化格式。但似乎没有任何方法可以从TypeAdapter或TypeAdapterFactory中访问字段注释。

这是我想要实现的一个例子。

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;
}

对于Movie对象,我想将日期序列化为“2013年8月24日星期六”,但对于LogEvent,“20130824T103025.123Z”。

我正在尝试这样做而不必为每个类编写单独的TypeAdapterFactory(想象一下,如果我们有100个不同的类,其中DateTime字段需要不同的格式)

TIA!

1 个答案:

答案 0 :(得分: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 {
      }
    };
  }
}