2012-10-25 41 views
7

假設我有XStream的序列化的空值

class Student 
{ 
String name; 
int age; 
String teacher; 
} 

然後:

public class App1 
{ 
    public static void main(String[] args) 
    { 
     Student st = new Student(); 
     st.setName("toto"); 

     XStream xs = new XStream(); 

     xs.alias("student",Student.class); 

     System.out.println(xs.toXML(st)); 
    } 

}

給我:

<student> 
    <name>toto</name> 
    <age>0</age> 
</student> 

是否有處理空值的方法嗎?我的意思是:

<student> 
    <name>toto</name> 
    <age>0</age> 
    <teacher></teacher> 
</student> 

這是可能的,如果我做

st.setTeacher(""); 

但如果老師爲null。

我試着用自定義轉換器,但它似乎沒有發送到轉換器的空值。

回答

1

首先提供getter和setter方法在你Student類,如下所示:

public class Student{ 
    String name; 
    int age; 
    String teacher; 
    public void setName(String name){ 
     this.name = name; 
    } 
    public String getName(){ 
     return name; 
    } 
....... 
......//Like that mention other getter and setter method 
} 

現在,所有你需要創建轉換器類,如下所示:

public class StudentConverter implements Converter{ 
    public boolean canConvert(Class clazz) { 
     return clazz.equals(Test.class); 
    } 
    public void marshal(Object value, HierarchicalStreamWriter writer, 
     MarshallingContext context) { 
     Student student = (Student) value; 
     writer.startNode("name"); 
     writer.setValue(test.getName()); 
     writer.endNode(); 
     writer.startNode("age"); 
     writer.setValue(test.getAge()); 
     writer.endNode(); 
     writer.startNode("teacher"); 
     writer.setValue(""); 
     writer.endNode(); 
    } 
    public Object unmarshal(HierarchicalStreamReader reader, 
     UnmarshallingContext context) { 
     Student student = new Student(); 
     test.setName(reader.getNodeName()); 
     test.setAge(reader.getNodeName()); 
     test.setTeacher(reader.getNodeName()); 
     return student; 
    } 
} 

Your main class will the like that: 

public class App1{ 
    public static void main(String args[]) { 
     XStream stream = new XStream(new StaxDriver()); 
     Student st = new Student(); 
     st.setName("ABC"); 
     t.setAge(21); 
     stream.registerConverter(new StudentConverter()); 
     stream.alias("student", Student.class); 
     System.out.println(stream.toXML(st)); 
    } 

} 

希望這是你的回答....快樂學習:)

2

我正在使用XStream 1.4.7,@XStreamAlias註釋爲自定義字段名稱,@ XStreamConverter爲自定義con轉換器(表示日期和其他自定義bean)。但是,空值的自定義轉換器甚至沒有被調用。 我的目標是序列化對象的所有字段,包括空字符,我不需要解組XML。

我設法通過創建一個自定義ReflectionConverter來做到這一點。 我從XStream庫擴展了ReflectionConverter並覆蓋了doMarshal方法。我唯一改變的是調用writeField方法無效info.values:

new Object() { 
{ 
    for (Iterator fieldIter = fields.iterator(); fieldIter.hasNext();) { 
     FieldInfo info = (FieldInfo) fieldIter.next(); 
     if (info.value != null) { 
      //leave the code unchanged 
      ... 
     } else { 
      //add this to write null info.value to xml 
      Log.info("MyCustomReflectionConverter -> serialize null field: " + info.fieldName); 
      writeField(info.fieldName, null, info.type, info.definedIn, info.value); 
     } 
    } 
    //... leave the rest of the code unchanged 
} 
}; 

在那之後,我創造了這樣的XSTREAM實例(它具有非常低的優先註冊您的轉換是非常重要的):

StaxDriver driver = new StaxDriver(new NoNameCoder()) { 
    @Override 
    public StaxWriter createStaxWriter(XMLStreamWriter out) throws XMLStreamException { 
     // the boolean parameter controls the production of XML declaration 
     return createStaxWriter(out, false); 
    } 
}; 

XStream xStream = new XStream(driver); 
xStream.autodetectAnnotations(true);//needed to process aliases 
//register MyCustomReflectionConverter 
MyCustomReflectionConverter reflectionConverter = new MyCustomReflectionConverter (xStream.getMapper(), new SunUnsafeReflectionProvider()); 
xStream.registerConverter(reflectionConverter, XStream.PRIORITY_VERY_LOW); 

感謝馬克Nabours爲他解決here

希望它能幫助。有沒有人找到更好的解決方案?

0

你可以把一個空字符串

String teacher = ""; 

或優化一個:)

String teacher = StringUtils.EMPTY;