gpt4 book ai didi

java - 无法使用 XStream/Jettison 反序列化多图

转载 作者:行者123 更新时间:2023-12-05 07:57:14 27 4
gpt4 key购买 nike

我正在尝试使用 XStream 和 Jettison 序列化和反序列化 Guava 的多重映射。这是一个简单的测试来说明:

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

它给出了以下错误:

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

请注意,当与枚举键一起使用时,此错误尤其集中在 Multimap 上。如果我使用 Map 而不是 multimap,则没有错误。如果我使用 String 而不是 Enum 作为键,则没有错误。此外,如果我序列化为 XML 而不是 JSON(也就是说,在构造函数中没有“JettisonMappedXmlDriver”),它会完美运行。

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

最佳答案

用XStream序列化Multimap的解决方案是使用Multimap转换器并注册到XStream,像这样:

public class MultimapConverter extends AbstractCollectionConverter {

public MultimapConverter(Mapper mapper) {
super(mapper);
}

@Override
public boolean canConvert(@SuppressWarnings("rawtypes") Class clazz) {
return Multimap.class.isAssignableFrom(clazz);
}

@Override
@SuppressWarnings("unchecked")
public void marshal(
Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
Multimap map = (Multimap) value;
for (Object key : map.keySet()) {
for (Object v : map.get(key)) {
if (v != null) {
writer.startNode("entry");
writer.addAttribute("key", key.toString());
writeCompleteItem(v, context, writer);
writer.endNode();
}
}
}
}

@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
ArrayListMultimap<Object, Object> map = ArrayListMultimap.create();
while (reader.hasMoreChildren()) {
reader.moveDown();
String key = reader.getAttribute("key");
Object value = null;
while (reader.hasMoreChildren()) {
reader.moveDown();
value = readBareItem(reader, context, map);
reader.moveUp();
}
reader.moveUp();

if (value != null) {
map.put(key, value);
}
}
return map;
}

}

然后将其注册到你拥有的XStream序列化器中,例如:

XStream xstream = new XStream(new JettisonMappedXmlDriver());
xstream.registerConverter(new MultimapConverter(xstream.getMapper()));
xstream.allowTypeHierarchy(Multimap.class);
xstream.addDefaultImplementation(ArrayListMultimap.class, Multimap.class);

至于反序列化上述转换器的错误按预期工作:

@Test
public void testSerializeWithEnum() {
XStream xstream = new XStream(new JettisonMappedXmlDriver());
xstream.registerConverter(new MultimapConverter(xstream.getMapper()));
xstream.allowTypeHierarchy(Multimap.class);
xstream.addDefaultImplementation(ArrayListMultimap.class, Multimap.class);
Multimap<TestEnum, String> test = HashMultimap.create();
test.put(TestEnum.E1, "test");
String json = xstream.toXML(test);
final Multimap<TestEnum, String> result = (Multimap<TestEnum, String>)xstream.fromXML(json);
}

public enum TestEnum {
E1
}

如果您在此处设置断点并调试 result 变量,您会看到 JSON 已使用枚举值反序列化。

关于java - 无法使用 XStream/Jettison 反序列化多图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27502648/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com