2012-10-25 21 views
7

Załóżmy, że mamXStream szeregować wartości null

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

Następnie:

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

}

daje mi:

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

Czy istnieje sposób do czynienia wartości null? To znaczy:

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

Jest to możliwe, jeśli robię

st.setTeacher(""); 

ale jeśli nauczyciel nie jest null.

Próbowałem z niestandardowym konwerterem, ale wydaje się, że wartości null nie są wysyłane do konwertera.

Odpowiedz

1

Przede wszystkim zawierają metody getter i setter w was Student klasy następująco:

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 
} 

Teraz wszystko, czego potrzebujesz, aby utworzyć klasę konwertera następująco:

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

} 

nadzieję, że to twoja odpowiedz .... Happy Learning :)

2

Używam adnotacji XStream 1.4.7, @XStreamAlias ​​dla niestandardowych nazw pól, @XStreamConverter dla niestandardowej konfiguracji verters (reprezentuje daty i inne niestandardowe komponenty). Jednak niestandardowy konwerter wartości null nie został nawet wywołany. Moim celem było serializowanie wszystkich pól obiektu, w tym zerowych, nie potrzebowałem nieprzyjemnego XML.

Udało mi się to zrobić, tworząc niestandardowy ReflectionConverter. Rozszerzyłem ReflectionConverter z biblioteki XStream i przejąłem metodę doMarshal. Jedyne co mi zostało zmienione wywołanie metody writeField dla zerowych 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 
} 
}; 

Potem stworzyłem instancji Xstream takiego (to jest bardzo ważne, aby zarejestrować swój przetwornik o bardzo niskim priorytecie):

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

Dzięki Mark Nabours dla jego rozwiązania here

Nadzieję, że to pomaga. Czy ktoś znalazł lepsze rozwiązanie?

0

Możesz umieścić pusty ciąg

String teacher = ""; 

lub optymalizowany jeden :)

String teacher = StringUtils.EMPTY; 
Powiązane problemy