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