2012-10-25 12 views
7

Angenommen habe ichXStream Serialisierung Nullwerte

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

Dann:

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

}

Gibt mir:

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

Gibt es eine Möglichkeit Nullwerte für den Umgang? Ich meine:

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

Es ist möglich, wenn ich

st.setTeacher(""); 

tun, aber nicht, wenn Lehrer ist null.

Ich versuchte mit einem benutzerdefinierten Konverter, aber es scheint, die Null-Werte werden nicht an den Konverter gesendet.

Antwort

1

Zunächst einmal bieten die Getter und Setter-Methoden in Ihnen Student Klasse wie folgt:

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 
} 

nun alles, was Sie benötigen, um Ihre Konverter-Klasse zu erstellen, wie folgt:

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

} 

Hoffe, es ist dein Antwort ... Happy Learning :)

2

Ich benutze XStream 1.4.7, @XStreamAlias ​​Annotation für benutzerdefinierte Feldnamen, @XStreamConverter für benutzerdefinierte con Verter (um Daten und andere benutzerdefinierte Beans darzustellen). Ein benutzerdefinierter Konverter für Nullwerte wurde jedoch nicht einmal aufgerufen. Mein Ziel war es, alle Felder des Objekts, einschließlich der Null, zu serialisieren, ich musste XML nicht entpacken.

Ich habe es geschafft, indem Sie einen benutzerdefinierten ReflectionConverter erstellen. Ich habe ReflectionConverter von der XStream-Bibliothek erweitert und die doMarshal-Methode übersteuert. Das einzige, was ich geändert ruft writeField Methode für null 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 
} 
}; 

Danach schaffte ich xStream Beispiel so (es ist sehr wichtig, um Ihre Konverter mit sehr niedriger Priorität registrieren):

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

Dank Mark Nabours für seine Lösung here

Hoffe, es hilft. Hat jemand eine bessere Lösung dafür gefunden?

0

können Sie legen einen leeren String

String teacher = ""; 

Oder optimiert one :)

String teacher = StringUtils.EMPTY;