2012-10-26 71 views
3

我有麻煩/使用JAXB的泛型類型unmarshall。 一切工作正常,但是當我的通用字段是日期(java.util.Date),解組將產生的XMLGregorianCalendar代替JAXB - 馬歇爾泛型(日期)

這裏的一段代碼我說的是:

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) 

你能幫助我如何解決?我曾想過一些適配器,這將是「積極的」,只在字段是日期,但我不認爲這是可能

感謝

+0

我猜你犯了一個錯誤,而錯誤與'ent2.getField()'是否一致? –

回答

1

一個JAXBContext是建立在階級,而不是類型。就您的JAXB(JSR-222)實現而言,field屬性的類型爲Object。如果將以下代碼添加到代碼中:

 String xml = sw.toString(); 
     System.out.println(xml); 

您將看到輸出XML如下。已添加xsi:type屬性以保留文本值包含日期信息。在自JAXB認爲屬性類型爲Object以來的unmarshal操作中,它將識別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> 
+0

你有什麼想法我可以教JAXB使用java.util.Date或任何其他日期實施? –

+0

首先可以使用一個適配器(它擴展了XMLAdapter)。第二種方法,收到消息後,使用xmlGregorianCalendar.toGregorianCalendar()。getTime()方法將其轉換爲日期對象。 –

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

我的日期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); 
    } 
} 

希望這是有益...