Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

simpleframework, deserializing an empty element to an empty string instead of null

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);
    }

});
like image 688
Sand Avatar asked Apr 13 '11 11:04

Sand


2 Answers

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.

like image 60
Sand Avatar answered Sep 19 '22 23:09

Sand


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

See Simple Framework Javadocs.

like image 45
Edwin Dalorzo Avatar answered Sep 22 '22 23:09

Edwin Dalorzo