gpt4 book ai didi

java - 如何使用 XStream 序列化/反序列化类型层次结构中的对象?

转载 作者:太空宇宙 更新时间:2023-11-04 07:29:16 24 4
gpt4 key购买 nike

我正在使用 XStream。目前,用其他东西替代 XStream 并不容易。

我有一个接口(interface) (MyInterface) 和几个实现该接口(interface)的子类(在下面的示例代码中,有一个名为 MyImplementation)。

我想序列化和反序列化子类的实例。我发现如果将 class 属性放入 XML 中,就可以很好地反序列化:

<myInterfaceElement class="myPackage.MyImplementation">
<field1>value1</field1>
<field2>value2</field2>
</myInterfaceElement>

但是,我不知道如何让XStream写入类属性。如何让 XStream 在序列化时包含类属性?或者是否有另一种方法来序列化/反序列化类层次结构,以便所有实现的元素名称都相同,并且每个子类都可以定义自己的字段?

这里是 MyInterface、MyImplementation 的示例,这是一个试图使其工作的 JUnit 测试用例。 deserializeWithClassAttribute 测试通过,而 classAttributeSetInResult 失败。

<小时/>
package myPackage;

public interface MyInterface {

}
<小时/>
package myPackage;

public class MyImplementation implements MyInterface {
public String field1;
public String field2;

public MyImplementation(String field1, String field2) {
this.field1 = field1;
this.field2 = field2;
}
}
<小时/>
package myPackage;
import org.junit.Test;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

import static org.junit.Assert.*;


public class xstreamTest {
@Test
public void classAttributeSetInResult() {
MyInterface objectToSerialize = new MyImplementation("value1", "value2");

final XStream xStream = new XStream(new DomDriver());
xStream.alias("myInterfaceElement", MyInterface.class);

String xmlResult = xStream.toXML(objectToSerialize).toString();

String expectedResult =
"<myInterfaceElement class=\"myPackage.MyImplementation\">\n" +
" <field1>value1</field1>\n" +
" <field2>value2</field2>\n" +
"</myInterfaceElement>";

assertEquals(expectedResult, xmlResult);
}

@Test
public void deserializeWithClassAttribute() {
String inputXmlString =
"<myInterfaceElement class=\"myPackage.MyImplementation\">\r\n" +
" <field1>value1</field1>\r\n" +
" <field2>value2</field2>\r\n" +
"</myInterfaceElement>";

final XStream xStream = new XStream(new DomDriver());

MyInterface result = (MyInterface)xStream.fromXML(inputXmlString);
assertTrue("Instance of MyImplementation returned", result instanceof MyImplementation);

MyImplementation resultAsMyImplementation = (MyImplementation)result;
assertEquals("Field 1 deserialized", "value1", resultAsMyImplementation.field1);
assertEquals("Field 2 deserialized", "value2", resultAsMyImplementation.field2);
}
}

最佳答案

我通过执行以下操作解决了这个问题(感谢 McD 提示使用转换器):

  1. 添加扩展 ReflectionConverter 的自定义转换器:

    package myPackage;

    import com.thoughtworks.xstream.converters.MarshallingContext;
    import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
    import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
    import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
    import com.thoughtworks.xstream.mapper.Mapper;

    public class MyInterfaceConverter extends ReflectionConverter {

    public MyInterfaceConverter(Mapper mapper, ReflectionProvider reflectionProvider) {
    super(mapper, reflectionProvider);
    }

    @Override
    public void marshal(Object original, final HierarchicalStreamWriter writer, final MarshallingContext context) {
    writer.addAttribute("class", original.getClass().getCanonicalName());
    super.marshal(original, writer, context);
    }

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

    }
  2. 在设置 xStream 时注册新转换器:

    @Test
    public void classAttributeSetInResult() {
    MyInterface objectToSerialize = new MyImplementation("value1", "value2");

    final XStream xStream = new XStream(new DomDriver());
    xStream.alias("myInterfaceElement", MyImplementation.class);
    xStream.registerConverter(new MyInterfaceConverter(xStream.getMapper(), xStream.getReflectionProvider()));

    String xmlResult = xStream.toXML(objectToSerialize).toString();

    String expectedResult =
    "<myInterfaceElement class=\"myPackage.MyImplementation\">\n" +
    " <field1>value1</field1>\n" +
    " <field2>value2</field2>\n" +
    "</myInterfaceElement>";

    assertEquals(expectedResult, xmlResult);
    }

希望这能对其他人有所帮助。如果有人有更好的想法,请告诉我!

关于java - 如何使用 XStream 序列化/反序列化类型层次结构中的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18018017/

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