序列化使用Gson以自定义方式将日期对象转换为JSON(注释)

时间:2017-05-29 11:33:13

标签: java android json gson

我有以下类的结构

class A {
  B b;
}

class B {
    @CustomDateFormat(
        format = "yyyy-MM-dd"
    )
    protected Date creationDate;
}

我希望以输出JSON具有使用注释@CustomDateFormat中的值格式化的creationDate字段的方式将类A的实例序列化为JSON。可能吗?理想情况下使用Gson。这将在Android上执行,因此没有Java 8具有ATM功能。

提前感谢任何想法

3 个答案:

答案 0 :(得分:2)

  

有可能吗?

排序。不幸的是,Gson几乎不支持自定义注释。但是,Gson对其@JsonAdapter注释进行原生支持,以便您可以模拟自定义注释。

让我们说,

final class A {

    final B b;

    A(final B b) {
        this.b = b;
    }

}
final class B {

    // Here comes an emulation for @CustomDateFormat(format = "yyyy-MM-dd")
    @JsonAdapter(YyyyMmDdDateTypeAdapter.class)
    final Date creationDate;

    B(final Date creationDate) {
        this.creationDate = creationDate;
    }

}
abstract class AbstractDateTypeAdapter
        extends TypeAdapter<Date> {

    protected abstract DateFormat getDateFormat();

    @Override
    @SuppressWarnings("resource")
    public final void write(final JsonWriter out, final Date value)
            throws IOException {
        out.value(getDateFormat().format(value));
    }

    @Override
    public final Date read(final JsonReader in) {
        throw new UnsupportedOperationException("Not implemented");
    }

}
final class YyyyMmDdDateTypeAdapter
        extends AbstractDateTypeAdapter {

    // Let Gson do it itself when needed
    private YyyyMmDdDateTypeAdapter() {
    }

    @Override
    protected DateFormat getDateFormat() {
        // SimpleDateFormat is known to be thread-unsafe so it has to be created everytime it's necessary
        // Maybe Joda Time is an option for you?
        // Joda Time date formatters are thread-safe and can be safely instantiated once per application
        return new SimpleDateFormat("yyyy-MM-dd");
    }

}

示例:

private static final Gson gson = new Gson();

public static void main(final String... args) {
    final A a = new A(new B(new Date()));
    final String json = gson.toJson(a);
    System.out.println(json);
}

输出:

  

{&#34; B&#34; {&#34; creationDate&#34;:&#34; 2017年5月29日&#34;}}

答案 1 :(得分:0)

如果static navigationOptions = { header: (navigation) => ({ title: <Text style={{ color: 'rgba(0, 0, 0, .9)', fontWeight: Platform.OS === 'ios' ? '600' : '500', fontSize: Platform.OS === 'ios' ? 17 : 18, alignSelf: 'center' }}>Filters</Text>, right: <SearchButton />, left: <CancelButton />, }) }; 的值是常数,那么您可以使用下面的代码

@CustomDataFormat

如果它不是常数,那么我认为你必须去反思读取带注释的值,然后应用上面的代码。

答案 2 :(得分:0)

最后我使用了反射,遍历了对象树并创建了一个关系Date - &gt;字符串(格式)。然后创建一个自定义序列化程序,并使用提到的地图相应地格式化日期。谢谢你的回答!!