2014-06-11 26 views
-1

我在ibm jdk(IBM-Java60-amd64)中生成了一個httpSession,並使用XStream將其解析爲xml。 我想在其他jdk(orecle-jdk1.6.0-x86)上重新創建此會話映射,但在反序列化時會發生錯誤。java XStream:jdks之間如何處理2個集合?

我西河對象:

public static XStream getXStreamConfigured(){ 

final XStream xstream = new XStream(){ 

    @Override 
    protected MapperWrapper wrapMapper(final MapperWrapper next){ 

    return new MapperWrapper(next) 
    { 

     @Override 
     public boolean shouldSerializeMember(
      final Class definedIn, 
      final String fieldName){ 

     if (definedIn == Object.class){ 
      return false; 
     } 

     return super.shouldSerializeMember(definedIn, fieldName); 
     } 

    };  
    } 

}; 

xstream.autodetectAnnotations(true); 

final String dateFormatXmlPattern = FundXmlHandler.DATE_FORMAT_VIEW_AND_XML_FORMAT; 
final DateConverter dateConverter = new XStreamConverterDate(dateFormatXmlPattern); 
xstream.registerConverter(dateConverter); 

return xstream; 

}

使用oracle JDK,在該輸出XML產生的一些標籤是這樣的:

<java.util.TreeMap_-KeySet> 
    <m class="tree-map"/> 
</java.util.TreeMap_-KeySet> 

使用IBM JDK,產生一些標籤在這個輸出xml是這樣的:

<java.util.TreeMap_-1> 
    <outer_class/> 
</java.util.TreeMap_-1> 

爲什麼它爲TreeMaps生成這個? 爲什麼我不能在oracle jdk中加載由ibm jdk生成的xml? 我怎麼能寫一個轉換器,在兩個jdk中生成相同的輸出?

我的堆棧:

---- Debugging information ---- 
message    : java.util.TreeMap$1 
cause-exception  : com.thoughtworks.xstream.mapper.CannotResolveClassException 
cause-message  : java.util.TreeMap$1 
class    : java.util.HashMap 
required-type  : java.util.HashMap 
converter-type  : com.thoughtworks.xstream.converters.collections.MapConverter 
path    : /map/entry[92]/java.util.TreeMap$1 
line number   : 161079 
version    : null 
------------------------------- 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:79) 
    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:1052) 
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1036) 
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:912) 
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:903) 
    at br.com.mindsatwork.vinci.rwf.util.UtilitiesRwf.loadSavedSessionObject(UtilitiesRwf.java:3222) 
    at br.com.mindsatwork.vinci.rwf.util.UtilitiesRwf.getFundDataFromSavedSession(UtilitiesRwf.java:1912) 
    at br.com.mindsatwork.vinci.rwf.web.action.ActionHandleSavedSession.getFundData(ActionHandleSavedSession.java:86) 
    at br.com.mindsatwork.vinci.rwf.web.action.AbstractActionWithFundDataUpload.executeIfLogged(AbstractActionWithFundDataUpload.java:88) 
    at br.com.mindsatwork.vinci.rwf.web.action.ActionHandleSavedSession.executeIfLogged(ActionHandleSavedSession.java:64) 
    at br.com.mindsatwork.vinci.rwf.web.action.AbstractActionWithLogin.executeAction(AbstractActionWithLogin.java:80) 
    at br.com.mindsatwork.vinci.rwf.web.action.AbstractVinciAction.executeAction(AbstractVinciAction.java:148) 
    at br.com.utilities.servlet.struts.action.AbstractStrutsActionWithDynaForm.executeAction(AbstractStrutsActionWithDynaForm.java:75) 
    at br.com.utilities.servlet.struts.action.AbstractStrutsAction.execute(AbstractStrutsAction.java:57) 
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:476) 
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:239) 
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1334) 
    at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:426) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) 
    at br.com.utilities.servlet.struts.AbstractStrutsAppServer.service(AbstractStrutsAppServer.java:344) 
    at br.com.mindsatwork.vinci.rwf.web.AppServer.service(AppServer.java:303) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:576) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399) 
    at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:306) 
    at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:322) 
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1732) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:662) 
Caused by: com.thoughtworks.xstream.mapper.CannotResolveClassException: java.util.TreeMap$1 
    at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:56) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:79) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30) 
    at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:45) 
    at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29) 
    at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:70) 
    at com.thoughtworks.xstream.converters.collections.MapConverter.putCurrentEntryIntoMap(MapConverter.java:89) 
    at com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:77) 
    at com.thoughtworks.xstream.converters.collections.MapConverter.populateMap(MapConverter.java:71) 
    at com.thoughtworks.xstream.converters.collections.MapConverter.unmarshal(MapConverter.java:66) 
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72) 
    ... 42 more 

我怎麼能寫一個泛型集合類型到這個輸出XML,可以組裝成不同的JDK?

鏈接http://x-stream.github.io/faq.html顯示XStream具有兩種操作模式:Pure Java和Enhanced(默認)。純Java據說可以與各種JVM一起使用。 我試圖用PureJavaReflectionProvider實例化XStream,使用Pure Java。

以下錯誤發生在同一個JVM:

com.thoughtworks.xstream.converters.ConversionException: Cannot construct java.util.TreeMap$KeySet as it does not have a no-args constructor : Cannot construct java.util.TreeMap$KeySet as it does not have a no-args constructor 
---- Debugging information ---- 
message    : Cannot construct java.util.TreeMap$KeySet as it does not have a no-args constructor 
cause-exception  : com.thoughtworks.xstream.converters.reflection.ObjectAccessException 
cause-message  : Cannot construct java.util.TreeMap$KeySet as it does not have a no-args constructor 
class    : java.util.TreeMap$KeySet 
required-type  : java.util.TreeMap$KeySet 
converter-type  : com.thoughtworks.xstream.converters.reflection.ReflectionConverter 
path    : /map/entry[93]/java.util.TreeMap$KeySet 
line number   : 36154 
class[1]   : java.util.HashMap 
converter-type[1] : com.thoughtworks.xstream.converters.collections.MapConverter 
version    : null 
------------------------------- 

回答

0

我會回答你的第一個問題開始:

爲什麼產生這樣的樹狀圖?

元素本地名稱爲java.util.TreeMap_-1,因爲XStream試圖序列化一個匿名內部類java.util.TreeMap

至於第二個問題:

我怎麼能寫一個泛型集合類型到這個輸出XML,可以組裝成不同的JDK?

您需要發佈更完整的代碼來演示此問題。請參閱SSCCE.org以瞭解需要哪些代碼。就目前來看,你還沒有提供足夠的例子讓別人重現這個問題。

我會根據您提供的內容對問題進行一些有根據的猜測。

開箱即用,XStream提供a number of converters,包括TreeMapConverterjava.util.TreeMap。當我運行的XStream的序列化對在我的環境一個TreeMap,我沒有看到任何的KeySet內部類,也不是一個匿名內部類正在連載:

import com.thoughtworks.xstream.XStream; 
import com.thoughtworks.xstream.mapper.MapperWrapper; 
import java.util.Date; 
import java.util.TreeMap; 

public class App { 

    public static XStream getXStreamConfigured() { 

     final XStream xstream = new XStream() { 

      @Override 
      protected MapperWrapper wrapMapper(final MapperWrapper next) { 

       return new MapperWrapper(next) { 

        @Override 
        public boolean shouldSerializeMember(
          final Class definedIn, 
          final String fieldName) { 

         if (definedIn == Object.class) { 
          return false; 
         } 

         return super.shouldSerializeMember(definedIn, fieldName); 
        } 

       }; 
      } 

     }; 

     xstream.autodetectAnnotations(true); 

     return xstream; 
    } 

    public static void main(String[] args) { 
     XStream xs = getXStreamConfigured(); 

     xs.toXML(new ExampleContainer().fill(), System.out); 
    } 

    public static class ExampleContainer { 

     private TreeMap<String, Date> map = new TreeMap<>(); 

     public ExampleContainer() { 
     } 

     public ExampleContainer fill() { 

      map.put("a", new Date()); 
      map.put("b", new Date()); 
      map.put("c", new Date()); 
      map.put("d", new Date()); 
      return this; 
     } 
    } 
} 

該代碼給我下面的輸出:

<App_-ExampleContainer> 
    <map> 
    <entry> 
     <string>a</string> 
     <date>2014-06-21 22:40:53.598 UTC</date> 
    </entry> 
    <entry> 
     <string>b</string> 
     <date>2014-06-21 22:40:53.598 UTC</date> 
    </entry> 
    <entry> 
     <string>c</string> 
     <date>2014-06-21 22:40:53.598 UTC</date> 
    </entry> 
    <entry> 
     <string>d</string> 
     <date>2014-06-21 22:40:53.598 UTC</date> 
    </entry> 
    </map> 
</App_-ExampleContainer> 

這似乎暗示着XStream正在使用它的默認轉換器,它使用反射來檢查類的成員是否爲TreeMap。造成這種情況的一些可能的原因包括對MapperWrapper的錯誤修改或者對不正確的Converter的註冊。

爲了更好的分析,請提供一個SSCCE來展示您的問題。

+0

好的。 謝謝你的回覆。我會提供SSCCE。 要重現此問題,我們需要安裝2個不同的jdk。在我的情況下,我使用ibm jdk 1.6(IBM-Java60-amd64)將xml和oracle jdk 1.6(orecle-jdk1.6.0-x86)序列化以再次構建集合。 –

+0

在每個jdk中,這個序列化在寫入xml時是不同的。 在oracle jdk中,輸出標記4的TreeMap是不同的。 所以我想生成一個可以在兩個jdks中組裝的xml。 我編輯了這個問題。 –

+0

對不起我的錯誤! –

0

我找到了我的問題的解決方案。

首先,我必須刪除所有匿名內部類,並將該代碼片段放入公共類中。例如,我將每個匿名比較器移動到特定的比較器類中。這也改進了設計。

我需要編寫一個MapConverter,一個CollectionConverter和一個ComparatorConverter來適當地序列化和組裝對象。 這個類擴展了XStream API提供的MapConverter,CollectionConverter和JavaBeanConverter。

我創建了一個靜態字符串ForbiddenClassesList,其中包含確定的jdk實現的所有特定類名。例如,我的名單有:

Collections.EMPTY_LIST.getClass()

Collections.singletonList(null).getClass()

在這種情況下,我只是簡單地忽略,系列化一個真正的空集 - new ArrayList(),在名帥方法執行。

我還對列表進行測試源類的名字,如:

{"java.util.TreeMap$KeySet","java.util.TreeMap$1"}

在我CollectionConverter

,不轉換和重定向物體向右轉換器,比如我MapConverter。

之後,一切工作正常! =)

避免所有匿名類,並在這些情況下實現特定的類。