2012-10-25 12 views
7

Giả sử tôi cóXStream serialize các giá trị null

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

Sau đó:

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

}

Cung cấp cho tôi:

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

Có cách nào để đối phó giá trị null? Ý tôi là:

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

Có thể nếu tôi làm

st.setTeacher(""); 

nhưng không nếu giáo viên là null.

Tôi đã thử với trình chuyển đổi tùy chỉnh nhưng có vẻ như giá trị null không được gửi đến trình chuyển đổi.

Trả lời

1

Trước hết cung cấp các phương pháp getter và setter trong bạn Student lớp như sau:

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 
} 

Bây giờ, tất cả các bạn cần phải tạo ra lớp chuyển đổi của bạn như sau:

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

} 

Hy vọng đó là của bạn answer .... Happy Learning :)

2

Tôi đang sử dụng chú thích XStream 1.4.7, @XStreamAlias ​​cho tên trường tùy chỉnh, @XStreamConverter cho con tùy chỉnh verters (để đại diện cho ngày tháng và các bean tùy chỉnh khác). Tuy nhiên, một bộ chuyển đổi tùy chỉnh cho các giá trị null thậm chí còn không được gọi. Mục tiêu của tôi là tuần tự hóa tất cả các trường của đối tượng, bao gồm cả các trường rỗng, tôi không cần unmarshal XML.

Tôi đã thực hiện điều đó bằng cách tạo Trình chỉnh sửa phản chiếu tùy chỉnh. Tôi mở rộng ReflectionConverter từ thư viện XStream và overrode phương pháp doMarshal. Điều duy nhất tôi đã thay đổi được cách gọi phương thức writeField cho info.values ​​null:

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

Sau đó, tôi tạo xStream dụ như vậy (nó là rất quan trọng để đăng ký chuyển đổi của bạn với ưu tiên rất thấp):

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

Nhờ Mark Nabours cho giải pháp của mình here

Hy vọng điều đó sẽ hữu ích. Có ai tìm thấy một giải pháp tốt hơn cho điều này?

0

Bạn có thể đặt một chuỗi rỗng

String teacher = ""; 

Hoặc tối ưu hóa một :)

String teacher = StringUtils.EMPTY;