本文介绍了如何将Java ZonedDateTime序列化为XML文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Error while serializing ZonedDateTime (it doesn't appear in the output xml at all):

java.lang.InstantiationException:java.time.ZonedDateTime

java.lang.InstantiationException: java.time.ZonedDateTime

继续...

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

java.lang.RuntimeException: failed to evaluate: =Class.new();

继续...

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

I have an instance of the class, where one of the fields is of a type ZonedDateTime.When i'm trying to serialize the object with XMLEncoder:

import java.beans.XMLEncoder;

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

I get this errors. In the output file all the other fields appear except the field with ZonedDateTime

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

this field with ZonedDateTime looks like this e.g.:

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

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

Is there a way to convert it to such date format that it will work?e.g.

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

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

The above writing (with .toLocalDateTime()) may not make any sense, but it's just the example.

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

I'm actually serializing the whole list of these objects, so the error appears many times (and always no output in xml file)

推荐答案

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

XMLEncoder and XMLDecoder are meant to work with regular Java bean classes. Typically, these are classes which have a public zero-argument constructor and public property accessor methods. There is some support for other classes, such as those with constructors that take property values, but most java.time classes are different and there is no built-in support for them.

幸运的是,您可以通过为要序列化的每个非Java Bean类指定一个PersistenceDelegate .

Fortunately, you can provide your own support, by specifying a PersistenceDelegate for each non-Java-bean class you plan to serialize.

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

So, the first step is providing a PersistenceDelegate for ZonedDateTime:

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.

But it turns out this is not enough, because the parts of the ZonedDateTime also get serialized, and one of them is a ZoneId. So we also need a PersistenceDelegate for ZoneId.

该PersistenceDelegate易于编写:

That PersistenceDelegate is easy to write:

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是一个抽象类,这意味着没有ZoneId对象,只有子类的实例.检查PersistenceDelegates时,XMLEncoder不参考继承.要序列化的每个对象的每个类都必须有一个PersistenceDelegate.

But registering it is not as easy. encoder.setPersistenceDelegate(ZoneId.class, zoneIdDelegate); won’t work, because ZoneId is an abstract class, which means there are no ZoneId objects, only instances of subclasses. XMLEncoder does not consult inheritance when checking for PersistenceDelegates. There must be a PersistenceDelegate for each class of every object to be serialized.

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

If you’re only serializing one ZonedDateTime, the solution is easy:

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

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

If you have a collection of them, you can check all of their 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值.

If you have aggregate objects containing ZonedDateTimes, you can simply iterate through them in a similar manner and access those ZonedDateTime values.

这篇关于如何将Java ZonedDateTime序列化为XML文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-12 06:04