我无法使用JAXB对通用类型进行编组/解组。 一切正常,但是当我的通用字段是Date(java.util.Date)时,解组将生成XMLGregorianCalendar而不是
这是我正在谈论的一段代码:
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Entity<T> {
private T field;
public Entity() {
}
public T getField() {
return field;
}
public void setField(T field) {
this.field = field;
}
}
import java.io.*;
import java.util.Date;
import javax.xml.bind.*;
public class JaxbTest {
public JaxbTest() {
Entity<Date> ent = new Entity<Date>();
ent.setField(new Date());
StringWriter sw = new StringWriter();
try {
// marshall
JAXBContext jaxbContext = JAXBContext.newInstance(Entity.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(ent, sw);
// unmarshall
JAXBContext jc = JAXBContext.newInstance(Entity.class);
Unmarshaller u = jc.createUnmarshaller();
Entity<Date> ent2 = (Entity<Date>) u.unmarshal(new StringReader(sw
.toString()));// exception is thrown here
System.out.println(ent2.getField());
} catch (JAXBException e11) {
e11.printStackTrace();
}
}
public static void main(String[] args) {
new JaxbTest();
}
}
上面的代码抛出异常:
java.lang.ClassCastException: com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl cannot be cast to java.util.Date
at JaxbTest.<init>(JaxbTest.java:31)
at JaxbTest.main(JaxbTest.java:38)
你能帮我解决一下吗?我正在考虑一些适用于&#34;活跃&#34;只有当字段是日期,但我认为不可能
感谢
答案 0 :(得分:1)
JAXBContext
是基于类而不是类型构建的。到目前为止,您的JAXB(JSR-222)实现都知道,field
属性的类型为Object
。如果您在代码中添加以下内容:
String xml = sw.toString();
System.out.println(xml);
您将看到输出XML如下所示。添加了xsi:type
属性以保留文本值包含日期信息。在unmarshal
操作,因为JAXB认为属性类型为Object
,它将识别xsi:type
属性并将值转换为默认日期类型XMLGregorianCalendar
。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<entity>
<field xsi:type="xs:dateTime" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">2012-10-29T15:20:17.763-04:00</field>
</entity>
答案 1 :(得分:0)
我在抽象类中遇到了与通用字段类似的问题。我通过添加带注释的getter / setter来解决它,它将值解析为字符串/从字符串中解析。然后在我的子类中覆盖getter / setter。
这是我的解决方案:
@XmlSeeAlso({DateEntity.class})
@XmlType
public abstract class Entity<T> {
private T field;
public Entity() {}
public T getField() {
return this.field;
}
public void setField(T field) {
this.field = field;
}
@XmlAttribute(name="value", required = true)
public abstract String getSerializeField();
public abstract void setSerializeField(String value);
}
我的日期sublcass:
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name="dateEntity")
public class DateEntity extends Entity<Date> {
public DateEntity() {}
@Override
public String getSerializeField(){
DateFormat formatter = DateFormat.getInstance();
return formatter.format(field);
}
@Override
public void setSerializeField(String value) {
DateFormat formatter = DateFormat.getInstance();
this.value = formatter.parse(value);
}
}
希望这有用......