javaserializationdeserializationsimple-framework

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

});

Solution

  • 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.