3

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)

修正方法を教えてください。フィールドが日付の場合にのみ「アクティブ」になるアダプタを考えていましたが、それは不可能だと思います

ありがとう

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

抽象クラスのジェネリック フィールドで同様の問題が発生しました。文字列との間で値を解析する注釈付きのゲッター/セッターを追加することで解決しました。ゲッター/セッターはサブクラスで上書きされます。

これが私の解決策でした:

@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 に答える