简单框架.空值可以保留在集合中吗? [英] Simpleframework. Can nulls be retained in collections?

查看:51
本文介绍了简单框架.空值可以保留在集合中吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须支持的一个项目中有一个对象-> 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]]

这篇关于简单框架.空值可以保留在集合中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆