java - 简单的框架。集合中可以保留空值吗?

标签 java xml simple-framework

在我必须支持的一个项目中有一个对象 -> XML -> 对象过程。 该对象包含列表,如果它被序列化,则列表中存在的所有空值都将被忽略。 我的问题是,它可以用 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 来防止空指针异常。到您列表的注释。但是,这并没有解决主要问题。

一般为空标签/null -元素不会被添加到结果中。


这是一个如何使用 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]]

关于java - 简单的框架。集合中可以保留空值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26386175/

相关文章:

java - 简单框架 XML : element with inner text and child elements

java - Spring Data Elasticsearch 可以很好地保存数据,但使用 findAll 返回空数组

java - 在JAVA servlet中放置/发布没有内容的请求

c# - 为什么 XmlSerializer 在映射具有相同名称但不同命名空间的类的对象图时无法初始化?

java - 简单 XML 的自定义转换器未从 xml 序列化为 java 对象

java - 在 Android 中使用简单 XML 并获取 NoClassDefFoundError

java - 如何在 Play Framework 的 session 中存储对象(不是字符串)?

java - 如何使用 Jackson 将 Object 类发送到服务器?

SQL-Server XML-Bulk-Import 和读取为表数据

java - 通过 fasterxml 将 XML 文件解析为 POJO 时出现异常 "No suitable constructor found for type [simple type..."