simpleframework, deserializing an empty element to

2020-07-10 05:33发布

I use simpleframework (http://simple.sourceforge.net/) in a project for my serializing / deserializing needs, but it doesn't work as expected (well, atleast not how I expect) when dealing with empty / null String values.

If I serialize an object with an empty String value, it will show as an empty xml element.

So this:

MyObject object = new MyObject();  
object.setAttribute(""); // attribute is String

would serialize as:

<object>  
  <attribute></attribute>  
</object>

But deserializing that empty attribute will end up as null, instead of an empty String.

Am I completely bonkers for thinking that it should be an empty String instead of null? And how on earth can I make it to work in the way I wan't?

Oh, and if I serialize the object with a null attribute it will end up showing <object/> as one might expect.

Edit:

Added a simple testcase I'm currenty running

@Test  
public void testDeserialization() throws Exception {  
    StringWriter writer = new StringWriter();  
    MyDTO dto = new MyDTO();  
    dto.setAttribute("");  

    Serializer serializer = new Persister();  
    serializer.write(dto, writer);  

    System.out.println(writer.getBuffer().toString());

    MyDTO read = serializer.read(MyDTO.class, writer.getBuffer().toString(),true);
    assertNotNull(read.getAttribute());  
}


@Root  
public class MyDTO {  
    @Element(required = false)  
    private String attribute;  

    public String getAttribute() {  
        return attribute;  
    }  

    public void setAttribute(String attribute) {  
        this.attribute = attribute;  
    }  
}  

Edit, fixed:

For some reason the InputNode value is null when an empty string is passed to it. I resolved the problem by creating a custom Converter for String.

new Converter<String>() {

    @Override
    public String read(InputNode node) throws Exception {
        if(node.getValue() == null) {
            return "";
        }
        return node.getValue();
    }

    @Override
    public void write(OutputNode node, String value) throws Exception {
        node.setValue(value);
    }

});

3条回答
够拽才男人
2楼-- · 2020-07-10 05:45

Answering for completeness

Annotate your element with the convert annotation and give it a converter class as a parameter @Convert(SimpleXMLStringConverter.class)

Create the converter class that does string conversion from null to empty string

public class SimpleXMLStringConverter implements Converter<String> {


    @Override
    public String read(InputNode node) throws Exception {
        String value = node.getValue();
        if(value == null) {
            value = "";
        }
        return value;
    } 

    @Override
    public void write(OutputNode node, String value) throws Exception {
        node.setValue(value);
    }

}

And don't for get to add new AnnotationStrategy() to your persister.

查看更多
SAY GOODBYE
3楼-- · 2020-07-10 06:00

Use the Attribute annotation. It has a property named empty used to provide a default value.

See Simple Framework Javadocs.

查看更多
乱世女痞
4楼-- · 2020-07-10 06:02

Am I completely bonkers for thinking that it should be an empty String instead of null?

Not as far as I know... Normally this indicates some problem with the Serialization along the way, it's supposed to return the Object and all it's non transient instance variable with the values set on Serialization.

BTW you didn't post all your code, it's also possible that the order in which the Serialization starts means it skips the String data this can sometime be a problem.

查看更多
登录 后发表回答