【问题标题】:GSON control serialization formatting by annotationGSON 通过注解控制序列化格式化
【发布时间】:2013-08-25 00:50:39
【问题描述】:

我正在尝试使用注释来控制序列化格式。但似乎没有任何方法可以从 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!

【问题讨论】:

    标签: java json gson


    【解决方案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 {
          }
        };
      }
    }
    

    【讨论】:

    • 在这个问题中,我试图避免的是必须为每个包含 DateTime 字段的类创建自定义适配器,因为我想在每个类中以不同的方式格式化该字段。但是,如果不重新实现 ReflectiveTypeAdapterFactory,这可能是不可能的。
    • 这是一个TypeAdapterFactory,不是一个特定的适配器,因此它应该适用于每个类。试试吧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多