如何将 Java ZonedDateTime 序列化为 XML 文件
How to serialize Java ZonedDateTime to XML file
序列化 ZonedDateTime 时出错(它根本没有出现在输出 xml 中):
java.lang.InstantiationException: java.time.ZonedDateTime
继续......
java.lang.RuntimeException:计算失败:=Class.new();
继续......
我有一个 class 的实例,其中一个字段属于 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")
上面的写法(with .toLocalDateTime())可能没有任何意义,但这只是例子。
我实际上是在序列化这些对象的整个列表,所以这个错误出现了很多次(并且在 xml 文件中总是没有输出)
XMLEncoder 和 XMLDecoder 旨在与常规 Java bean classes 一起工作。通常,这些是 classes,它们具有 public 零参数构造函数和 public 属性 访问器方法。对其他 classes 有一些支持,例如那些具有采用 属性 值的构造函数的那些,但大多数 java.time classes 是不同的并且没有内置支持为了他们。
幸运的是,您可以通过 specifying a PersistenceDelegate 为您计划序列化的每个非 Java-bean class 提供自己的支持。
因此,第一步是为 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。所以我们还需要一个用于 ZoneId 的 PersistenceDelegate。
那个PersistenceDelegate好写:
PersistenceDelegate zoneIdDelegate = new PersistenceDelegate() {
@Override
protected Expression instantiate(Object target,
Encoder encoder) {
ZoneId other = (ZoneId) target;
return new Expression(other, ZoneId.class, "of",
new Object[] { other.getId() });
}
};
但是注册起来并不容易。 encoder.setPersistenceDelegate(ZoneId.class, zoneIdDelegate);
不会起作用,因为 ZoneId 是一个抽象的 class,这意味着没有 ZoneId 对象,只有 subclasses 的实例。 XMLEncoder 在检查 PersistenceDelegates 时不参考继承。每个要序列化的对象的每个 class 都必须有一个 PersistenceDelegate。
如果你只序列化一个 ZonedDateTime,解决方案很简单:
encoder.setPersistenceDelegate(
date.getZone().getClass(), zoneIdDelegate);
如果你有它们的集合,你可以检查它们的所有 ZoneId classes:
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 值。
序列化 ZonedDateTime 时出错(它根本没有出现在输出 xml 中):
java.lang.InstantiationException: java.time.ZonedDateTime
继续......
java.lang.RuntimeException:计算失败:=Class.new();
继续......
我有一个 class 的实例,其中一个字段属于 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")
上面的写法(with .toLocalDateTime())可能没有任何意义,但这只是例子。
我实际上是在序列化这些对象的整个列表,所以这个错误出现了很多次(并且在 xml 文件中总是没有输出)
XMLEncoder 和 XMLDecoder 旨在与常规 Java bean classes 一起工作。通常,这些是 classes,它们具有 public 零参数构造函数和 public 属性 访问器方法。对其他 classes 有一些支持,例如那些具有采用 属性 值的构造函数的那些,但大多数 java.time classes 是不同的并且没有内置支持为了他们。
幸运的是,您可以通过 specifying a PersistenceDelegate 为您计划序列化的每个非 Java-bean class 提供自己的支持。
因此,第一步是为 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。所以我们还需要一个用于 ZoneId 的 PersistenceDelegate。
那个PersistenceDelegate好写:
PersistenceDelegate zoneIdDelegate = new PersistenceDelegate() {
@Override
protected Expression instantiate(Object target,
Encoder encoder) {
ZoneId other = (ZoneId) target;
return new Expression(other, ZoneId.class, "of",
new Object[] { other.getId() });
}
};
但是注册起来并不容易。 encoder.setPersistenceDelegate(ZoneId.class, zoneIdDelegate);
不会起作用,因为 ZoneId 是一个抽象的 class,这意味着没有 ZoneId 对象,只有 subclasses 的实例。 XMLEncoder 在检查 PersistenceDelegates 时不参考继承。每个要序列化的对象的每个 class 都必须有一个 PersistenceDelegate。
如果你只序列化一个 ZonedDateTime,解决方案很简单:
encoder.setPersistenceDelegate(
date.getZone().getClass(), zoneIdDelegate);
如果你有它们的集合,你可以检查它们的所有 ZoneId classes:
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 值。