2014-09-22 79 views
0

首先需要一些背景信息,如果格式不正確,請原諒我。XStream編組反彙編XMLGregorianCalendar和Java.util.Date

我想要通過XML來回映射兩個對象。一個是通過wsimport自動生成的,所以我無法使用JAXB或XStream標註。另一個是由我們正在實施的工具自動生成的。

我在這種情況下,我試圖將兩個對象映射到彼此是相同的日期字段上一個是Java.util.Date的另一個是XMLGregorian日曆。

我覺得最快的方法,而不是一個巨大的手動映射過程將是使用XStream 抓住XML String交換周圍的根元素和序列化到另一個對象。那時我遇到了轉換日期的問題。我嘗試過使用轉換器,但又遇到了另一個轉換問題。我希望有人能夠幫助我。

我有兩個測試實體:

import java.util.Date; 

    import javax.xml.datatype.XMLGregorianCalendar; 
    import com.eccles.utilities.*; 

    public class SampleEntityGregorian { 

     private XMLGregorianCalendar date = DateUtils.xmlGregCalFromDate(new Date()); 

     public XMLGregorianCalendar getGregCal() { 
      return date; 
     } 

     public void setGregCal(XMLGregorianCalendar gregCal) { 
      this.date = gregCal; 
     } 

    } 

而且

import java.util.Date; 

    public class SampleEntityJavaUtil { 

     private Date date = new Date(); 

     public Date getUtilDate() { 
      return date; 
     } 

     public void setUtilDate(Date utilDate) { 
      this.date = utilDate; 
     } 

    } 

我有我與西河/解組從之間jav.util.date和註冊的XMLGregorianCalendar馬歇爾自定義轉換二。

import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.GregorianCalendar; 
import java.util.Locale; 

import javax.xml.datatype.DatatypeConfigurationException; 
import javax.xml.datatype.DatatypeFactory; 
import javax.xml.datatype.XMLGregorianCalendar; 

import com.thoughtworks.xstream.converters.Converter; 
import com.thoughtworks.xstream.converters.MarshallingContext; 
import com.thoughtworks.xstream.converters.UnmarshallingContext; 
import com.thoughtworks.xstream.io.HierarchicalStreamReader; 
import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 

public class FromJavaUtilDateConverter implements Converter { 

    public FromJavaUtilDateConverter() { 
    } 

    public boolean canConvert(Class clazz) { 

     System.out.println("****CAN CONVERT " + clazz.getName() + "?***"); 
     System.out.println("Class name = " + clazz.getName()); 
     System.out.println(java.util.Date.class.isAssignableFrom(clazz)); 
     System.out.println("\n"); 

     return java.util.Date.class.isAssignableFrom(clazz); 

    } 

    public void marshal(Object value, HierarchicalStreamWriter writer, 
        MarshallingContext context) { 
     System.out.println("***MARSHALLING*** \n"); 

     Date date = (Date) value; 

     writer.setValue(date.toString()); 

    } 

    public Object unmarshal(HierarchicalStreamReader reader, 
        UnmarshallingContext context){ 
     System.out.println("**UNMARSHALLING**"); 

     XMLGregorianCalendar result = null; 

     try { 

     String readerString = reader.getValue(); 
     System.out.println("Reader value = " + readerString + "\n");  

     GregorianCalendar gregorianCalendar; 

     SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy"); 

     Date date = sdf.parse(readerString); 
     System.out.println("parsed string to date = " + date.toString()); 

     gregorianCalendar = (GregorianCalendar)GregorianCalendar.getInstance(); 

     gregorianCalendar.setTime(date); 
     System.out.println("Gregorian Calendar from Date = " + gregorianCalendar.getTime() + "\n"); 

     result = DatatypeFactory.newInstance().newXMLGregorianCalendar(gregorianCalendar); 
     System.out.println("XML Gregorian Calendar = " + result.toXMLFormat() + "\n"); 

     //System.out.println(result.t); 

     } catch (ParseException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     catch (DatatypeConfigurationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return result;  
    } 

} 

這是我的測試:

@Test 
public void testSerializationToGregCalendar(){  

    SampleEntityJavaUtil entityJavaUtil = new SampleEntityJavaUtil(); 

    XStream xs = new XStream(); 
    xs.registerConverter(new FromJavaUtilDateConverter()); 
    xs.alias("SampleEntityGregorian.class",SampleEntityJavaUtil.class); 

    String entityJavaUtilString = xs.toXML(entityJavaUtil); 
    System.out.println("Entity with Java Util Date:" + "\n"); 
    System.out.println(entityJavaUtilString); 
    System.out.println("\n"); 

    SampleEntityGregorian entityGregCal = new SampleEntityGregorian(); 

    System.out.println(xs.toXML(entityGregCal)); 

    try{ 
     entityGregCal = (SampleEntityGregorian) xs.fromXML(entityJavaUtilString); 
    } 
    catch(Exception e){ 
     System.out.println("Failed to Serialize"); 
     e.printStackTrace(); 
    } 

} 

和異常:

com.thoughtworks.xstream.converters.ConversionException: Cannot convert type com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl to type java.util.Date 
---- Debugging information ---- 
class    : SampleEntityJavaUtil 
required-type  : SampleEntityJavaUtil 
converter-type  : com.thoughtworks.xstream.converters.reflection.ReflectionConverter 
path    : /SampleEntityGregorian.class/date 
line number   : 2 
version    : 1.4.7 
------------------------------- 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:430) 
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:257) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134) 
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32) 
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1185) 
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1169) 
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1040) 
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1031) 
    at com.eccles.tests.ConverterTests.testSerializationToGregCalendar(ConverterTests.java:87) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

在此先感謝。

蒂姆

回答

0

我會說你是一個非常狂野的東西。

如果你唯一的問題是使用的日期類型,你可以嘗試定製JAXB部分(wsimport,無論)使用日期而不是XMLGregorianCalender。對此,Heres的一個link

接下來,您可能要考慮使用諸如Dozer之類的東西來映射Bean而不是重新映射。

這可能是一個非常膚淺的觀點,但從我看過的方法看起來並不適合我。你在一個問題中提到了wsimport/JAXB,XStream和一個自己的工具。這不適合我。

+0

嗨lexicore,謝謝你的評論。這不是我想要進入的位置,而是被迫走下這條路。 將重試自定義綁定並強制wsimport生成日期作爲java.util.date而不是XMLGregorianCalendar。 最後一次我做到了這一點,我結束了兩個希望XStream自定義轉換器將能夠解決的格式不匹配... – 2014-09-23 08:24:07

+0

如果我只能弄清楚爲什麼XStream不能轉換什麼是由自定義返回轉換器,將解決問題... – 2014-09-23 10:16:32

+0

對不起,不能幫助XStream。 – lexicore 2014-09-23 10:19:45