2014-09-22 5 views
0

형식이 올바르지 않으면 먼저 약간의 배경 정보를 보내주십시오. 용서해주세요.XStream 마샬링 XMLGregorianCalendar 및 Java.util.Date

XML을 통해 앞뒤로 매핑하려고하는 두 개의 개체가 있습니다. 하나는 wsimport를 통해 자동 생성되므로 JAXB 또는 XStream 주석을 사용할 수 없습니다. 다른 하나는 구현중인 도구에 의해 자동 생성됩니다.

두 객체를 서로 매핑하는 중일 때 하나의 Date 필드가 Java.util.Date이고 다른 하나는 XMLGregorian 캘린더가 아닌 다른 객체를 매핑하려고하는 상황입니다.

엄청난 수작업 매핑 프로세스 대신에 가장 빠른 방법은 XStream 을 사용하여 XML 문자열을 잡아 내고 루트 요소를 스왑하고 다른 객체로 직렬화하는 것입니다. 그것이 날짜를 변환하는 문제를 만났습니다. 나는 변환기를 사용하려고했지만 또 다른 변환 문제가 발생했습니다. 나는 누군가가 이것으로 나를 도울 수 있기를 바랍니다.

나는 두 개의 시험 기관이 있습니다

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에서 마샬에 XStream을에 등록하고 사용자 정의 변환이를 두.

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

감사

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

} 

는 그리고 이건 내 테스트입니다.

답변

0

나는 당신이 꽤 까다로운 일이라고 말하고 싶습니다.

유일한 문제는 사용 된 날짜 유형 인 경우 XMLGregorianCalender 대신 Date를 사용하도록 JAXB 부분 (wsimport, 무엇이든)을 사용자 정의 할 수 있습니다. Heres는 그것에 대해 link입니다.

다음으로 리마 르싱 대신 빈 사이를 매핑하려면 Dozer과 같은 것을 사용하는 것이 좋습니다.

이것은 매우 피상적 ​​인 의견 일 수도 있지만, 내가 읽은 접근법이 내게 맞는 것처럼 보이지 않습니다. 한 질문에서 wsimport/JAXB, XStream 및 자체 도구에 대해 언급합니다. 그건 나에게 맞는 것 같지 않아.

+0

안녕하세요 lexicore, 귀하의 의견에 감사드립니다. 내가 속한 위치가 아니지만이 길을 강요당했습니다. 사용자 지정 바인딩을 다시 시도하고 wsimport가 XMLGregorianCalendar가 아닌 java.util.date로 날짜를 생성하도록합니다. 내가 마지막으로이 작업을 수행 한 결과, XStream 사용자 지정 변환기가 해결할 수있는 두 형식 간의 형식 불일치가 발생했습니다. –

+0

XStream이 사용자 지정에서 반환되는 내용을 변환 할 수없는 이유를 파악할 수만 있다면 변환기 문제를 해결할 것입니다 ... –

+0

죄송합니다, XStream 도와 드릴 수 없습니다. – lexicore