我必须支持的一个项目中有一个对象-> XML->对象过程。该对象包含List,并且如果将其序列化,则会省略list中存在的所有空值。我的问题是,可以使用Simpleframework完成还是应该使用其他方法?什么?这是我的工作:
import java.io.StringWriter; import java.util.Arrays; import java.util.List; import org.simpleframework.xml.Attribute; import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; import org.simpleframework.xml.core.Persister; import org.testng.annotations.Test; public class SimpleframeworkTest { @Test public void testNullsInParams() throws Exception { Container container = new Container(); container.setId(4000); container.setParams(Arrays.asList(new Object[] { "foo", null, "bar" })); String xml = container.toXml(); // omits null value in output } @Test public void testDeserializeNull() throws Exception { String xml = "<container id=\"4000\">"+ " <object class=\"java.lang.String\">foo</object>"+ // " <object class=\"java.lang.String\"></object>"+ // gets NullPointerException here " <object class=\"java.lang.String\">bar</object>"+ "</container>"; Container object = Container.toObject(xml); } @Root(name = "container", strict = false) public static class Container { @Attribute private Integer id; @ElementList(inline = true, required = false) private List<Object> params; public String toXml() throws Exception { StringWriter sw = new StringWriter(); new Persister().write(this, sw); return sw.toString(); } public static Container toObject(String xml) throws Exception { return new Persister().read(Container.class, xml); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public List<Object> getParams() { return params; } public void setParams(List<Object> params) { this.params = params; } @Override public String toString() { return "Container [id=" + id + ", params=" + params + "]"; } } }
首先,您的列表注释缺少条目名称:
@ElementList(inline = true, required = false, entry = "object") private List<Object> params;
否则<string>...</string>,不使用<object>...</object>。 您可以通过添加type = String.class到列表的注释中来防止空指针异常。但是,这不能解决主要问题。
<string>...</string>
<object>...</object>
type = String.class
通常,空标记/- null元素不会添加到结果中。
null
这是一个使用来解决此问题的示例Converter。
Converter
public class SimpleframeworkTest { // ... @Root(name = "container", strict = false) @Convert(NullawareContainerConverter.class) public static class Container { static final Serializer ser = new Persister(new AnnotationStrategy()); // ... public String toXml() throws Exception { StringWriter sw = new StringWriter(); ser.write(this, sw); return sw.toString(); } public static Container toObject(String xml) throws Exception { return ser.read(Container.class, xml); } // ... } static class NullawareContainerConverter implements Converter<Container> { final Serializer ser = new Persister(); @Override public Container read(InputNode node) throws Exception { final Container c = new Container(); c.id = Integer.valueOf(node.getAttribute("id").getValue()); c.params = new ArrayList<>(); InputNode n; while( ( n = node.getNext("object")) != null ) { /* * If the value is null it's added too. You also can add some * kind of null-replacement element here too. */ c.params.add(n.getValue()); } return c; } @Override public void write(OutputNode node, Container value) throws Exception { ser.write(value.id, node); for( Object obj : value.params ) { if( obj == null ) { obj = ""; // Set a valid value if null } // Possible you have to tweak this by hand ser.write(obj, node); } } } }
如评论中所写,您必须做一些进一步的工作。
结果:
testNullsInParams()
<container> <integer>4000</integer> <string>foo</string> <string></string> <string>bar</string> </container>
testDeserializeNull()
Container [id=4000, params=[foo, null, bar]]