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

}

给我 :

  toto 0  

有没有办法处理空值? 我的意思是 :

  toto 0   

如果我这样做可能

 st.setTeacher(""); 

但如果老师是空的,那就没有。

我尝试使用自定义转换器,但似乎空值不会发送到转换器。

我正在使用XStream 1.4.7,@ XStreamAlias注释用于自定义字段名称,@ XStreamConverter用于自定义转换器(用于表示日期和其他自定义bean)。 但是,甚至没有调用空值的自定义转换器。 我的目标是序列化对象的所有字段,包括null字段,我不需要解组XML。

我设法通过创建自定义ReflectionConverter来做到这一点。 我从XStream库扩展了ReflectionConverter并覆盖了doMarshal方法。 我唯一改变的是为null info.values调用writeField方法:

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

感谢Mark Nabours的解决方案

希望能帮助到你。 有人找到了更好的解决方案吗?

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

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

希望这是你的答案….快乐学习:)

你可以放一个空字符串

 String teacher = ""; 

或优化一个:)

 String teacher = StringUtils.EMPTY;