Jör*_*ann 4 java calendar jaxb
我正在使用如下所示的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>
Run Code Online (Sandbox Code Playgroud)
我想将日期和时间映射到我的bean中的单个Date或Calendar属性.这可能是使用jaxb注释吗?该类javax.xml.bind.annotation.adapters.XmlAdapter似乎可以做到这一点,但我不得不承认我并不完全理解它的javadoc.
解决方法是为日期和时间字符串创建其他setter,以便在Calendar属性中设置相应的值,如下所示:
private Calendar calendar;
public void setDate(String date) {
if (calendar == null) {
calendar = new GregorianCalendar();
}
calendar.set(YEAR, Integer.parseIn(date.substring(0, 4)));
calendar.set(MONTH, Integer.parseIn(date.substring(4, 6))-1);
calendar.set(DAY_OF_MONTH, Integer.parseIn(date.substring(6, 8)));
}
// Similar code for setTime
Run Code Online (Sandbox Code Playgroud)
问题(除了附加代码)是我不能总是保证日期在时间值之前设置,但我想不出一个具体的例子,这可能会给出结果.
可以理解基于注释的解决方案的任何示例或上述代码的改进/反例.
编辑:我接受了Blaise Doughan给出的第二个答案,但修改了他的DateAttributeTransformer更灵活,并且不希望字段名称包含字符串"DATE".字段名称取自字段上的XmlWriterTransformer注释:
@Override
public Object buildAttributeValue(Record record, Object instance, Session session) {
try {
String dateString = null;
String timeString = null;
String dateFieldName = null;
String timeFieldName = null;
// TODO: Proper Exception handling
try {
XmlWriteTransformers wts = instance.getClass().getDeclaredField(mapping.getAttributeName()).getAnnotation(XmlWriteTransformers.class);
for (XmlWriteTransformer wt : wts.value()) {
String fieldName = wt.xpath();
if (wt.transformerClass() == DateFieldTransformer.class) {
dateFieldName = fieldName;
} else {
timeFieldName = fieldName;
}
}
} catch (NoSuchFieldException ex) {
throw new RuntimeException(ex);
} catch (SecurityException ex) {
throw new RuntimeException(ex);
}
for(DatabaseField field : mapping.getFields()) {
XMLField xfield = (XMLField)field;
if(xfield.getXPath().equals(dateFieldName)) {
dateString = (String) record.get(field);
} else {
timeString = (String) record.get(field);
}
}
return yyyyMMddHHmmss.parseObject(dateString + timeString);
} catch(ParseException e) {
throw new RuntimeException(e);
}
}
Run Code Online (Sandbox Code Playgroud)
XmlAdapter是正确的方法:
具有Date属性的类
import java.util.Date;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement(name="ROOT")
public class Root {
private Date date;
@XmlElement(name="ELEM")
@XmlJavaTypeAdapter(DateAdapter.class)
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
Run Code Online (Sandbox Code Playgroud)
XmlAdapter的实现
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class DateAdapter extends XmlAdapter<AdaptedDate, Date> {
private SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyyMMdd");
private SimpleDateFormat HHmmss = new SimpleDateFormat("HHmmss");
private SimpleDateFormat yyyyMMddHHmmss = new SimpleDateFormat("yyyyMMddHHmmss");
@Override
public Date unmarshal(AdaptedDate v) throws Exception {
String dateString = v.getDate() + v.getTime();
return yyyyMMddHHmmss.parse(dateString);
}
@Override
public AdaptedDate marshal(Date v) throws Exception {
AdaptedDate adaptedDate = new AdaptedDate();
adaptedDate.setDate(yyyyMMdd.format(v));
adaptedDate.setTime(HHmmss.format(v));
return adaptedDate;
}
}
Run Code Online (Sandbox Code Playgroud)
改编的Date对象
import javax.xml.bind.annotation.XmlElement;
public class AdaptedDate {
private String date;
private String time;
@XmlElement(name="DATE")
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
@XmlElement(name="TIME")
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
Run Code Online (Sandbox Code Playgroud)
示例程序
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);
File xml = new File("input.xml");
Unmarshaller unmarshaller = jc.createUnmarshaller();
Root root = (Root) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
Run Code Online (Sandbox Code Playgroud)
XML文档
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<ELEM>
<DATE>20100825</DATE>
<TIME>141500</TIME>
</ELEM>
</ROOT>
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅