我正在使用XStream。目前,用其他方法替换XStream并不容易。我有一个接口(MyInterface)和实现该接口的几个子类(在下面的示例代码中,有一个名为MyImplementation)。如何使用XStream对类型层次结构中的对象进行序列化/反序列化?
我想序列化和反序列化子类的实例。我发现,如果我把类属性到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);
}
}
当然,你是对的。使用像这些简单类的“标准”XStream序列化机制要好得多。 我从我需要定制转换器的更复杂的类中选择我的示例。 – MrD
好主意。我发现手动添加类名作为属性会产生一个异常,因为它已经被XStream自动添加了。将编辑您的答案以包含解组方法的示例。 – ScarOnTheSky