您可以使用MOXy JAXB实现(我是技术负责人),而不是使用jaxbri(Metro)。它有一些扩展,可以使映射这个场景相当容易。
jaxb.properties属性
要使用MOXy作为JAXB实现,需要添加一个名为jaxb.properties属性在与模型类相同的包中,具有以下条目:
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
import javax.xml.bind.annotation.*;
@XmlRootElement(name="ROOT")
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlElement(name="ELEM_A")
private ElemA elemA;
@XmlElement(name="ELEM_B")
private ElemB elemB;
}
埃莱玛
我们可以利用@XmlTransformation。它在概念上类似于XmlAdapter,但更容易在映射之间共享。
import java.util.Date;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import org.eclipse.persistence.oxm.annotations.XmlReadTransformer;
import org.eclipse.persistence.oxm.annotations.XmlTransformation;
import org.eclipse.persistence.oxm.annotations.XmlWriteTransformer;
import org.eclipse.persistence.oxm.annotations.XmlWriteTransformers;
@XmlAccessorType(XmlAccessType.FIELD)
public class ElemA {
@XmlTransformation
@XmlReadTransformer(transformerClass=DateAttributeTransformer.class)
@XmlWriteTransformers({
@XmlWriteTransformer(xpath="A_DATE/text()", transformerClass=DateFieldTransformer.class),
@XmlWriteTransformer(xpath="A_TIME/text()", transformerClass=TimeFieldTransformer.class),
})
public Date aDate;
@XmlElement(name="STRING")
private String string;
}
埃伦布
import java.util.Date;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import org.eclipse.persistence.oxm.annotations.XmlReadTransformer;
import org.eclipse.persistence.oxm.annotations.XmlTransformation;
import org.eclipse.persistence.oxm.annotations.XmlWriteTransformer;
import org.eclipse.persistence.oxm.annotations.XmlWriteTransformers;
@XmlAccessorType(XmlAccessType.FIELD)
public class ElemB {
@XmlTransformation
@XmlReadTransformer(transformerClass=DateAttributeTransformer.class)
@XmlWriteTransformers({
@XmlWriteTransformer(xpath="B_DATE/text()", transformerClass=DateFieldTransformer.class),
@XmlWriteTransformer(xpath="B_TIME/text()", transformerClass=TimeFieldTransformer.class),
})
private Date bDate;
@XmlElement(name="NUM")
private int num;
@XmlTransformation
@XmlReadTransformer(transformerClass=DateAttributeTransformer.class)
@XmlWriteTransformers({
@XmlWriteTransformer(xpath="C_DATE/text()", transformerClass=DateFieldTransformer.class),
@XmlWriteTransformer(xpath="C_TIME/text()", transformerClass=TimeFieldTransformer.class),
})
private Date cDate;
}
日期属性转换器
import java.text.ParseException;
import java.text.SimpleDateFormat;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping;
import org.eclipse.persistence.mappings.transformers.AttributeTransformer;
import org.eclipse.persistence.sessions.Record;
import org.eclipse.persistence.sessions.Session;
public class DateAttributeTransformer implements AttributeTransformer {
private AbstractTransformationMapping mapping;
private SimpleDateFormat yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss");
public void initialize(AbstractTransformationMapping mapping) {
this.mapping = mapping;
}
public Object buildAttributeValue(Record record, Object instance, Session session) {
try {
String dateString = null;
String timeString = null;
for(DatabaseField field : mapping.getFields()) {
if(field.getName().contains("DATE")) {
dateString = (String) record.get(field);
} else {
timeString = (String) record.get(field);
}
}
return yyyyMMddHHmmss.parseObject(dateString + timeString);
} catch(ParseException e) {
throw new RuntimeException(e);
}
}
}
DateFieldTransformer公司
场转换器负责编组日期对象。
import java.text.SimpleDateFormat;
import java.util.Date;
import org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping;
import org.eclipse.persistence.mappings.transformers.FieldTransformer;
import org.eclipse.persistence.sessions.Session;
public class DateFieldTransformer implements FieldTransformer {
private AbstractTransformationMapping mapping;
private SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyyMMdd");
public void initialize(AbstractTransformationMapping mapping) {
this.mapping = mapping;
}
public Object buildFieldValue(Object instance, String xPath, Session session) {
Date date = (Date) mapping.getAttributeValueFromObject(instance);
return yyyyMMdd.format(date);
}
}
import java.text.SimpleDateFormat;
import java.util.Date;
import org.eclipse.persistence.mappings.foundation.AbstractTransformationMapping;
import org.eclipse.persistence.mappings.transformers.FieldTransformer;
import org.eclipse.persistence.sessions.Session;
public class TimeFieldTransformer implements FieldTransformer {
private AbstractTransformationMapping mapping;
private SimpleDateFormat HHmmss = new SimpleDateFormat("HHmmss");
public void initialize(AbstractTransformationMapping mapping) {
this.mapping = mapping;
}
public Object buildFieldValue(Object instance, String xPath, Session session) {
Date date = (Date) mapping.getAttributeValueFromObject(instance);
return HHmmss.format(date);
}
}
示例程序
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
System.out.println(jc);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum41/input.xml");
Root root = (Root) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
XML文档
<ROOT>
<ELEM_A>
<A_DATE>20100825</A_DATE>
<A_TIME>141500</A_TIME>
<!-- other elements, maybe also other or date/time combinations -->
<STRING>ABC</STRING>
</ELEM_A>
<ELEM_B>
<B_DATE>20100825</B_DATE>
<B_TIME>153000</B_TIME>
<NUM>123</NUM>
<C_DATE>20100825</C_DATE>
<C_TIME>154500</C_TIME>
</ELEM_B>
</ROOT>
当前发布的EclipseLink 2.1版本支持上述功能,但配置略有不同。如果您有兴趣探索此选项,我们可以讨论适当的设置。