JAXB - 马歇尔泛型类型(日期)

时间:2012-10-26 09:41:53

标签: java generics jaxb

我无法使用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;只有当字段是日期,但我认为不可能

感谢

2 个答案:

答案 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);
    }
}

希望这有用......