首先需要一些背景信息,如果格式不正確,請原諒我。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)
在此先感謝。
蒂姆
嗨lexicore,謝謝你的評論。這不是我想要進入的位置,而是被迫走下這條路。 將重試自定義綁定並強制wsimport生成日期作爲java.util.date而不是XMLGregorianCalendar。 最後一次我做到了這一點,我結束了兩個希望XStream自定義轉換器將能夠解決的格式不匹配... – 2014-09-23 08:24:07
如果我只能弄清楚爲什麼XStream不能轉換什麼是由自定義返回轉換器,將解決問題... – 2014-09-23 10:16:32
對不起,不能幫助XStream。 – lexicore 2014-09-23 10:19:45