问题描述
我必须支持的一个项目中有一个对象-> XML->对象过程.该对象包含List,如果将其序列化,则列表中存在的所有空值都将被省略.我的问题是,可以使用Simpleframework完成还是应该使用其他方法?什么?这是我的工作:
I have a object -> XML -> object process in one project I have to support.The object is containing List and if it gets serialized, all the null values which where present in list are omitted.My question is, can it be done with Simpleframework or should I use something else? What?Here is what I do:
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 + "]";
}
}
}
推荐答案
首先,您的列表注释缺少条目名称:
First, your list annotation is missing the the entries name:
@ElementList(inline = true, required = false, entry = "object")
private List<Object> params;
否则使用< string> ...</string>
,而不使用< object> ...</object>
.
您可以通过在列表的注释中添加 type = String.class
来防止空指针异常.但是,这不能解决主要问题.
Otherwise <string>...</string>
is used, not <object>...</object>
.
You can prevent that nullpointer excpetion by adding type = String.class
to your list's annotation. However, this doesn't fix the main problem.
通常,空标记/ null
-元素不会添加到结果中.
In general empty tags / null
-elements will not be added to the result.
以下是使用 Converter
来解决此问题的示例.
Here's an example how to solve this problem with a 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);
}
}
}
}
根据评论中的内容,您需要做一些进一步的工作.
As written in the comments, you have to do some further work.
结果:
testNullsInParams()
testNullsInParams()
<container>
<integer>4000</integer>
<string>foo</string>
<string></string>
<string>bar</string>
</container>
testDeserializeNull()
testDeserializeNull()
Container [id=4000, params=[foo, null, bar]]
这篇关于简单框架.空值可以保留在集合中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!