我尝试使用Xstream序列化Java中的对象列表,我的核心代码是:
//register alias
xstream.alias("category", ServerCategory.class);
//register converter
xstream.registerConverter(new ServerCategoryConverter());
// get all categories
List<ServerCategory> categoryList = categoryDao.getAllEager();
// serialize all categories
for(ServerCategory category : categoryList) {
xstream.toXML(category, streamWriter);
}
这很好用,但我在</category>
- 标签之后没有换行,这似乎与xml规范冲突导致每个读者都在此行中断。
有没有解决这个问题?
答案 0 :(得分:2)
您当前的代码将生成以下内容:
<category>
<id>1</id>
<name>One</name>
<description>One</description>
<syncversion>V1</syncversion>
<parents/>
</category>
<category>
<id>2</id>
<name>Two</name>
<description>Two</description>
<syncversion>V1</syncversion>
<parents>
<parent>1</parent>
</parents>
</category>
这是无效的xml,因为它应该有一个根元素(这个xml有多个根元素类别) 理想情况下,您应该生成这样的。 您可以在浏览器中打开以下内容。
<list> <!-- one root element required!!-->
<category>
<id>1</id>
<name>One</name>
<description>One</description>
<syncversion>V1</syncversion>
<parents/>
</category>
<category>
<id>2</id>
<name>Two</name>
<description>Two</description>
<syncversion>V1</syncversion>
<parents>
<parent>1</parent>
</parents>
</category>
<list>
需要做的不是
for(ServerCategory category : categoryList) {
xstream.toXML(category, streamWriter);
}
你应该序列化整个列表
xstream.toXML(categoryList, streamWriter);
并且应使用
覆盖您的ServerCategoryConverter canCovert()public boolean canConvert(Class foo) {
//dont use this converter for the Arraylist. Arraylist will be handeld by the default converter
if (foo.getName().equals("java.util.ArrayList")) {
return false;
}
return true;
}
我已附上我的完整代码供参考。它适用于上述修复:
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
public class XSTReamTest {
/*
* ExpertService.class
*/
public static void main(String args[]) throws Exception {
XSTReamTest tst = new XSTReamTest();
tst.createXmlExport();
}
public File createXmlExport() throws Exception {
XStream xstream = new XStream();
File xmlExportFile = null;
BufferedOutputStream outputStream = null;
OutputStreamWriter streamWriter = null;
try {
xmlExportFile = new File("easylearncards1_exportRequest_.xml");
System.out.println("Path = " + xmlExportFile.getAbsolutePath());
outputStream = new BufferedOutputStream(new FileOutputStream(xmlExportFile));
streamWriter = new OutputStreamWriter(outputStream, Charset.forName("UTF-8"));
exportCategories(xstream, streamWriter);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
streamWriter.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return xmlExportFile;
}
private void exportCategories(XStream xstream, OutputStreamWriter streamWriter) {
// register alias
xstream.alias("category", ServerCategory.class);
// register converter
xstream.registerConverter(new ServerCategoryConverter());
// get all categories
List<ServerCategory> categoryList = new ArrayList<ServerCategory>();
ServerCategory root = new ServerCategory("1", "One", "One", "V1", null);
ServerCategory child1 = new ServerCategory("2", "Two", "Two", "V1", new ServerCategory[]{root});
ServerCategory child2 = new ServerCategory("3", "Three", "Three", "V1", new ServerCategory[]{root});
ServerCategory child3 = new ServerCategory("4", "Four", "Four", "V1", new ServerCategory[]{child1, child2});
categoryList.add(root);
categoryList.add(child1);
categoryList.add(child2);
categoryList.add(child3);
// convert all categories
// for (ServerCategory category : categoryList) {
// xstream.toXML(category, streamWriter);
// }
xstream.toXML(categoryList, streamWriter);
}
static class ServerCategory {
String id;
String name;
String description;
String syncVersion;
ServerCategory parents[];
ServerCategory(String id, String name, String description, String syncVersion, ServerCategory[] parents) {
this.id = id;
this.name = name;
this.description = description;
this.syncVersion = syncVersion;
this.parents = parents;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getSyncVersion() {
return syncVersion;
}
public void setSyncVersion(String syncVersion) {
this.syncVersion = syncVersion;
}
public ServerCategory[] getParents() {
return parents;
}
public void setParents(ServerCategory[] parents) {
this.parents = parents;
}
}
/*
* ServerCategoryConverter.class
*/
static class ServerCategoryConverter implements Converter {
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
ServerCategory category = (ServerCategory) value;
writer.startNode("id");
writer.setValue(category.getId().toString());
writer.endNode();
writer.startNode("name");
writer.setValue(category.getName());
writer.endNode();
writer.startNode("description");
writer.setValue(category.getDescription());
writer.endNode();
writer.startNode("syncversion");
writer.setValue(category.getSyncVersion().toString());
writer.endNode();
writer.startNode("parents");
if (category.getParents() != null) {
for (ServerCategory parent : category.getParents()) {
writer.startNode("parent");
writer.setValue(parent.getId().toString());
writer.endNode();
}
}
writer.endNode();
}
public java.lang.Object unmarshal(com.thoughtworks.xstream.io.HierarchicalStreamReader hierarchicalStreamReader, com.thoughtworks.xstream.converters.UnmarshallingContext unmarshallingContext) {
return null;
}
public boolean canConvert(Class foo) {
if (foo.getName().equals("java.util.ArrayList")) {
return false;
}
return true;
}
}
}