Java 无法使用XStream/Jettison反序列化多重映射

Java 无法使用XStream/Jettison反序列化多重映射,java,guava,xstream,jettison,Java,Guava,Xstream,Jettison,我正在尝试使用XStream和抛弃对番石榴的多重映射进行序列化和反序列化。下面是一个简单的测试来说明: final XStream xstream = new XStream(new JettisonMappedXmlDriver()); final Multimap<TestEnum, String> test = HashMultimap.create(); test.put(TestEnum.E1, "test"); final String j

我正在尝试使用XStream和抛弃对番石榴的多重映射进行序列化和反序列化。下面是一个简单的测试来说明:

    final XStream xstream = new XStream(new JettisonMappedXmlDriver());
    final Multimap<TestEnum, String> test = HashMultimap.create();
    test.put(TestEnum.E1, "test");
    final String json = xstream.toXML(test);
    final Multimap<TestEnum, String> result = (Multimap<TestEnum, String>)xstream.fromXML(json);
请注意,当与枚举键一起使用时,此错误尤其集中在Multimap上。如果我使用Map而不是multimap,就不会有错误。如果我使用字符串而不是枚举作为键,就不会有错误。此外,如果我序列化为XML而不是JSON(也就是说,在构造函数中没有“JettisonMappedXmlDriver”),那么它可以完美地工作


有什么好的解决办法吗?我目前正在使用一种变通方法,将我的多重映射替换为集合映射,但我更愿意找到一种方法来保留多重映射。

使用XStream序列化多重映射的解决方案是使用多重映射转换器并注册到XStream,如下所示:

公共类MultimapConverter扩展了AbstractCollectionConverter{ 公共多重映射转换器(映射器映射器){ 超级(制图员); } @凌驾 公共布尔canConvert(@SuppressWarnings(“rawtypes”)类clazz){ 返回Multimap.class.isAssignableFrom(clazz); } @凌驾 @抑制警告(“未选中”) 公共无效执法官( 对象值,HierarchycalStreamWriter编写器,封送上下文){ 多映射映射=(多映射)值; for(对象键:map.keySet()){ for(对象v:map.get(键)){ 如果(v!=null){ 作者:startNode(“条目”); writer.addAttribute(“key”,key.toString()); writeCompleteItem(v、上下文、作者); writer.endNode(); } } } } @凌驾 公共对象解组(HierarchycalStreamReader读取器,解组上下文){ ArrayListMultimap=ArrayListMultimap.create(); while(reader.hasMoreChildren()){ reader.moveDown(); String key=reader.getAttribute(“key”); 对象值=空; while(reader.hasMoreChildren()){ reader.moveDown(); 值=readBareItem(读取器、上下文、映射); reader.moveUp(); } reader.moveUp(); if(值!=null){ map.put(键、值); } } 返回图; } } 然后将其注册到您拥有的XStream序列化程序,例如:

XStream XStream=newxstream(new-JettisonMappedXmlDriver());
registerConverter(新的多映射转换器(xstream.getMapper());
allowTypeHierarchy(Multimap.class);
addDefaultImplementation(ArrayListMultimap.class,Multimap.class);
对于反序列化上述转换器时出现的错误,其工作原理与预期一致:

@测试
public void testSerializeWithEnum(){
XStream XStream=newxstream(new-JettisonMappedXmlDriver());
registerConverter(新的多映射转换器(xstream.getMapper());
allowTypeHierarchy(Multimap.class);
addDefaultImplementation(ArrayListMultimap.class,Multimap.class);
Multimap test=HashMultimap.create();
test.put(TestEnum.E1,“测试”);
字符串json=xstream.toXML(test);
最终的多重映射结果=(多重映射)xstream.fromXML(json);
}
公共枚举测试数{
E1
}
如果您在这里放置断点并调试
result
变量,您将看到JSON是用枚举值反序列化的

com.thoughtworks.xstream.converters.ConversionException: Could not call com.google.common.collect.HashMultimap.readObject() : com.test.Test$TestEnum cannot be cast to java.lang.Integer
---- Debugging information ----
message             : Could not call com.google.common.collect.HashMultimap.readObject()
cause-exception     : java.lang.ClassCastException
cause-message       : com.test.Test$TestEnum cannot be cast to java.lang.Integer
class               : com.google.common.collect.HashMultimap
required-type       : com.google.common.collect.HashMultimap
converter-type      : com.thoughtworks.xstream.converters.reflection.SerializableConverter
path                : /com.google.common.collect.HashMultimap/com.google.common.collect.HashMultimap
line number         : -1
version             : 1.4.7
-------------------------------