7

シリアル化/逆シリアル化のニーズのためにプロジェクトでsimpleframework(http://simple.sourceforge.net/)を使用していますが、空/ nullの文字列値を処理するときに期待どおりに機能しません(少なくとも私が期待する方法ではありません) 。

空の文字列値を持つオブジェクトをシリアル化すると、空のxml要素として表示されます。

したがって、この:

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

次のようにシリアル化します。

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

ただし、その空の属性を逆シリアル化すると、空の文字列ではなくnullになります。

私はそれがnullではなく空の文字列であるべきだと考えるのに完全に腹を立てていますか?そして、一体どうやって私が望まない方法でそれを機能させることができますか?

ああ、null属性を使用してオブジェクトをシリアル化すると、 <object/> 予想どおりに表示されるようになります。

編集:

現在実行している簡単なテストケースを追加しました

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

編集、修正:

InputNode空の文字列が渡されると、何らかの理由で値がnullになります。のカスタムコンバーターを作成することで問題を解決しました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);
    }

});
4

3 に答える 3

10

完全性のために答える

要素にconvertアノテーションを付け、コンバータークラスをパラメーターとして指定します @Convert(SimpleXMLStringConverter.class)

nullから空の文字列への文字列変換を行うコンバータークラスを作成します

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

}

そして、あなたのパーシスターに追加するために取得しないでnew AnnotationStrategy()ください。

于 2011-04-18T06:22:49.570 に答える
2

属性アノテーションを使用します。デフォルト値を提供するために使用されるemptyという名前のプロパティがあります。

SimpleFrameworkJavadocを参照してください。

于 2011-04-13T12:19:55.987 に答える
-1

私はそれがnullではなく空の文字列であるべきだと考えるのに完全に腹を立てていますか?

私の知る限りではありません...通常、これは途中でシリアル化に問題があることを示しています。オブジェクトと、シリアル化で設定された値を持つすべての非一時的なインスタンス変数を返すことになっています。

ところで、すべてのコードを投稿しなかった場合、シリアル化が開始される順序が文字列データをスキップすることを意味する可能性もあります。これは問題になる場合があります。

于 2011-04-13T12:19:57.630 に答える