如何将Java ZonedDateTime序列化为XML文件

序列化ZonedDateTime时出错(它根本不会出现在输出xml中):

java.lang.InstantiationException:java.time.ZonedDateTime

继续...

java.lang.RuntimeException:无法评估:= Class.new();

继续...

我有一个类的实例,其中一个字段的类型为ZonedDateTime。 当我尝试使用XMLEncoder序列化对象时:

import java.beans.XMLEncoder;

我收到此错误。在输出文件中,除带有ZonedDateTime的字段外,所有其他字段都会出现

具有ZonedDateTime的此字段如下所示:

ZonedDateTime date = ZonedDateTime.parse("2010-01-10T00:00:00Z[CET]");

是否可以将其转换为可以使用的日期格式? 例如

ZonedDateTime.parse("2010-01-10T00:00:00").toLocalDateTime().atZone(ZoneId.of("CET")

上面的文字(带有.toLocalDateTime())可能没有任何意义,但这只是示例。

我实际上是在序列化这些对象的整个列表,因此错误多次出现(并且在xml文件中始终没有输出)

qq9931 回答:如何将Java ZonedDateTime序列化为XML文件

XMLEncoder和XMLDecoder旨在与常规Java Bean类一起使用。通常,这些类具有公共零参数构造函数和公共属性访问器方法。对其他类也有一些支持,例如那些带有采用属性值的构造函数的类,但是大多数java.time类是不同的,并且没有内置支持。

幸运的是,您可以specifying a PersistenceDelegate为计划序列化的每个非Java Bean类提供自己的支持。

因此,第一步是为ZonedDateTime提供一个PersistenceDelegate:

PersistenceDelegate zonedDateTimeDelegate = new PersistenceDelegate() {
    @Override
    protected Expression instantiate(Object target,Encoder encoder) {
        ZonedDateTime other = (ZonedDateTime) target;
        return new Expression(other,ZonedDateTime.class,"of",new Object[] {
                other.getYear(),other.getMonthValue(),other.getDayOfMonth(),other.getHour(),other.getMinute(),other.getSecond(),other.getNano(),other.getZone()
            });
    }
};

encoder.setPersistenceDelegate(
    ZonedDateTime.class,zonedDateTimeDelegate);

但是事实证明这还不够,因为ZonedDateTime的部分也被序列化了,其中之一就是ZoneId。因此,我们还需要一个PersistenceDelegate作为ZoneId。

该PersistenceDelegate易于编写:

PersistenceDelegate zoneIdDelegate = new PersistenceDelegate() {
    @Override
    protected Expression instantiate(Object target,Encoder encoder) {
        ZoneId other = (ZoneId) target;
        return new Expression(other,ZoneId.class,new Object[] { other.getId() });
    }
};

但是注册它并不容易。 encoder.setPersistenceDelegate(ZoneId.class,zoneIdDelegate);不起作用,因为ZoneId是一个抽象类,这意味着没有ZoneId对象,只有子类的实例。检查PersistenceDelegates时,XMLEncoder不参考继承。要序列化的每个对象的每个类都必须有一个PersistenceDelegate。

如果仅序列化一个ZonedDateTime,则解决方案很简单:

encoder.setPersistenceDelegate(
    date.getZone().getClass(),zoneIdDelegate);

如果您有它们的集合,则可以检查所有它们的ZoneId类:

Set<Class<? extends ZoneId>> zoneClasses = new HashSet<>();
for (ZonedDateTime date : dates) {
    Class<? extends ZoneId> zoneClass = date.getZone().getClass();
    if (zoneClasses.add(zoneClass)) {
        encoder.setPersistenceDelegate(zoneClass,zoneIdDelegate);
    }
}

如果您有包含ZonedDateTimes的聚合对象,则可以简单地以类似的方式遍历它们并访问那些ZonedDateTime值。

本文链接:https://www.f2er.com/3120949.html

大家都在问