3

我无法使用 JAXB 编组/解组泛型类型。一切正常,但是当我的通用字段是日期(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)

你能帮我解决一下吗?我正在考虑一些只有当字段是日期时才会“活动”的适配器,但我认为这是不可能的

谢谢

4

2 回答 2

1

AJAXBContext建立在类而不是类型之上。就您的 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>
于 2012-10-29T19:23:42.377 回答
0

我对抽象类中的通用字段有类似的问题。我通过添加一个带注释的 getter/setter 来解决它,该 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);
}

我的日期子类:

@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);
    }
}

希望这会有所帮助...

于 2016-05-25T13:31:56.200 回答