我正在构建一系列链接类,其实例我希望能够编组为XML,这样我就可以将它们保存到文件中并稍后再读取它们。
目前我使用以下代码作为测试用例:
import javax.xml.bind.annotation.*;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.time.LocalDate;
public class LocalDateExample
{
@XmlRootElement
private static class WrapperTest {
public LocalDate startDate;
}
public static void main(String[] args) throws JAXBException
{
WrapperTest wt = new WrapperTest();
LocalDate ld = LocalDate.of(2016, 3, 1);
wt.startDate = ld;
marshall(wt);
}
public static void marshall(Object jaxbObject) throws JAXBException
{
JAXBContext context = JAXBContext.newInstance(jaxbObject.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(jaxbObject, System.out);
}
}
XML输出是:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wrapperTest>
<startDate/>
</wrapperTest>
startDate
元素为空是否有原因?我希望它包含日期的字符串表示(即toString()
)。为了做到这一点,我是否需要编写自己的代码?
java -version
的输出是:
openjdk version "1.8.0_66-internal"
OpenJDK Runtime Environment (build 1.8.0_66-internal-b17)
OpenJDK 64-Bit Server VM (build 25.66-b17, mixed mode)
答案 0 :(得分:34)
您必须像这样创建XmlAdapter
:
public class LocalDateAdapter extends XmlAdapter<String, LocalDate> {
public LocalDate unmarshal(String v) throws Exception {
return LocalDate.parse(v);
}
public String marshal(LocalDate v) throws Exception {
return v.toString();
}
}
使用
注释您的字段 @XmlJavaTypeAdapter(value = LocalDateAdapter.class)
如果要在包级别定义适配器,请参阅javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters
。
答案 1 :(得分:4)
http://blog.bdoughan.com/2011/05/jaxb-and-joda-time-dates-and-times.html描述了洞穴设置。
Joda-Time提供了Java SE中当前提供的日期和日历类的替代方法。由于它们是在单独的库中提供的,因此JAXB不为这些类提供默认映射。
为包中的所有文件注册适配器。您可以在要注册的包中添加package-info.java。
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(type=LocalDate.class,
value=LocalDateAdapter.class),
})
package PACKAGE_NAME;
import java.time.LocalDate;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
适配器看起来像:
import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.time.LocalDate;
public class LocalDateAdapter extends XmlAdapter<String, LocalDate>{
public LocalDate unmarshal(String v) throws Exception {
return LocalDate.parse(v);
}
public String marshal(LocalDate v) throws Exception {
return v.toString();
}
}
答案 2 :(得分:0)
作为 Nikolay Antipov mentioned in this commment,已经有一个经过充分测试的 threeten
库,provides 14 type adapters(截至 2021-04-26)其中之一是:
并且可以使用例如在某些 Java 领域是这样的(虽然我一般不推荐):
@XmlJavaTypeAdapter(value = LocalDateXmlAdapter.class) myLocalDt;
相反,我会推荐 package-info.java
方法在包级别的每个包中隐式执行此操作,以便它自动应用于例如所有包类中 LocalDate
类型的所有字段:
创建一个名为 src/java/my/xmlconv/classes/package-info.java
的文件
其内容:
@XmlJavaTypeAdapters({
@XmlJavaTypeAdapter(value=LocalDateTimeXmlAdapter.class, type=LocalDateTime.class)
})
package my.xmlconv.classes;
import java.time.LocalDateTime;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
import io.github.threetenjaxb.core.LocalDateTimeXmlAdapter;