为 ZonedDateTime 编写 xstream 转换器
Writing xstream Converter for ZonedDateTime
为了从日历更改为 ZonedDateTime (java.time),我必须为 xstream 编写 ZonedDateTime 转换器。
在这篇文章中 https://github.com/x-stream/xstream/issues/24 被建议
What you can actually do is writing a custom converter for ZonedDateTime where the type is represented as String. Use this String representation to convert back into a ZonedDateTime instance.<<
我尝试了两种方法:第一种是扩展 com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter
,第二种是实现 com.thoughtworks.xstream.converters.Converter
。
这是第二种方法的代码:
public class ZonedDateTimeConverter implements Converter
{
@Override
public boolean canConvert(Class type)
{
return (type != null) && (ZonedDateTime.class.equals(type));
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer,
MarshallingContext context)
{
ZonedDateTime zonedDateTime = (ZonedDateTime) source;
writer.setValue(zonedDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
}
@Override
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context)
{
return ZonedDateTime.parse(reader.getValue(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}
}
我注册转换器:
XStream xstream = new XStream();
xstream.registerConverter(new ZonedDateTimeConverter());
但我总是得到一个错误:
com.thoughtworks.xstream.converters.ConversionException: Cannot deserialize object with new readObject()/writeObject() methods
---- Debugging information ----
class : java.time.ZonedDateTime
required-type : java.time.ZonedDateTime
converter-type : com.thoughtworks.xstream.converters.reflection.SerializableConverter
path : /de.unigreifswald.floradb.importer.model.ImportJob/exportDate
line number : 5
class[1] : de.unigreifswald.floradb.importer.model.ImportJob
converter-type[1] : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
version : 1.4.6
-------------------------------
at com.thoughtworks.xstream.converters.reflection.SerializableConverter.doUnmarshal(SerializableConverter.java:331)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:257)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:474)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:406)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:257)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1157)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1141)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1105)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1047)
at de.unigreifswald.floradb.importer.persistence.ImportJobDaoBeanSerialization.read(ImportJobDaoBeanSerialization.java:74)
at de.unigreifswald.floradb.importer.persistence.ImportJobDaoBeanSerialization.visitFile(ImportJobDaoBeanSerialization.java:92)
at de.unigreifswald.floradb.importer.persistence.ImportJobDaoBeanSerialization.visitFile(ImportJobDaoBeanSerialization.java:1)
at java.nio.file.Files.walkFileTree(Files.java:2670)
at java.nio.file.Files.walkFileTree(Files.java:2742)
at de.unigreifswald.floradb.importer.persistence.ImportJobDaoBeanSerialization.get(ImportJobDaoBeanSerialization.java:84)
at de.unigreifswald.floradb.importer.persistence.TestImportJobDaoBeanSerilaization.testPersist(TestImportJobDaoBeanSerilaization.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)
我该怎么做才能解决这个问题?
在 https://github.com/x-stream/xstream/issues/24 上,joehni 提到 xstream 的新版本可以处理 java.time,这是事实。我从 xtream 1.4.6 更新到 1.4.10,现在 ZonedDateTime 处理得很好。
为了从日历更改为 ZonedDateTime (java.time),我必须为 xstream 编写 ZonedDateTime 转换器。 在这篇文章中 https://github.com/x-stream/xstream/issues/24 被建议
What you can actually do is writing a custom converter for ZonedDateTime where the type is represented as String. Use this String representation to convert back into a ZonedDateTime instance.<<
我尝试了两种方法:第一种是扩展 com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter
,第二种是实现 com.thoughtworks.xstream.converters.Converter
。
这是第二种方法的代码:
public class ZonedDateTimeConverter implements Converter
{
@Override
public boolean canConvert(Class type)
{
return (type != null) && (ZonedDateTime.class.equals(type));
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer,
MarshallingContext context)
{
ZonedDateTime zonedDateTime = (ZonedDateTime) source;
writer.setValue(zonedDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
}
@Override
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context)
{
return ZonedDateTime.parse(reader.getValue(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}
}
我注册转换器:
XStream xstream = new XStream();
xstream.registerConverter(new ZonedDateTimeConverter());
但我总是得到一个错误:
com.thoughtworks.xstream.converters.ConversionException: Cannot deserialize object with new readObject()/writeObject() methods
---- Debugging information ----
class : java.time.ZonedDateTime
required-type : java.time.ZonedDateTime
converter-type : com.thoughtworks.xstream.converters.reflection.SerializableConverter
path : /de.unigreifswald.floradb.importer.model.ImportJob/exportDate
line number : 5
class[1] : de.unigreifswald.floradb.importer.model.ImportJob
converter-type[1] : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
version : 1.4.6
-------------------------------
at com.thoughtworks.xstream.converters.reflection.SerializableConverter.doUnmarshal(SerializableConverter.java:331)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:257)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:474)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:406)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:257)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1157)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1141)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1105)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1047)
at de.unigreifswald.floradb.importer.persistence.ImportJobDaoBeanSerialization.read(ImportJobDaoBeanSerialization.java:74)
at de.unigreifswald.floradb.importer.persistence.ImportJobDaoBeanSerialization.visitFile(ImportJobDaoBeanSerialization.java:92)
at de.unigreifswald.floradb.importer.persistence.ImportJobDaoBeanSerialization.visitFile(ImportJobDaoBeanSerialization.java:1)
at java.nio.file.Files.walkFileTree(Files.java:2670)
at java.nio.file.Files.walkFileTree(Files.java:2742)
at de.unigreifswald.floradb.importer.persistence.ImportJobDaoBeanSerialization.get(ImportJobDaoBeanSerialization.java:84)
at de.unigreifswald.floradb.importer.persistence.TestImportJobDaoBeanSerilaization.testPersist(TestImportJobDaoBeanSerilaization.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=13=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:539)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:761)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:461)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:207)
我该怎么做才能解决这个问题?
在 https://github.com/x-stream/xstream/issues/24 上,joehni 提到 xstream 的新版本可以处理 java.time,这是事实。我从 xtream 1.4.6 更新到 1.4.10,现在 ZonedDateTime 处理得很好。