问题描述
假设我有
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>
有没有办法处理空值?我的意思是:
Is there a way for dealing null values ? I mean :
<student>
<name>toto</name>
<age>0</age>
<teacher></teacher>
</student>
如果我这样做可能
st.setTeacher("");
但如果老师为空则不会。
but not if teacher is null.
我尝试使用自定义转换器,但似乎空值不会发送到转换器。
I tried with a custom converter but it seems the null values are not sent to the converter.
推荐答案
我正在使用XStream 1.4.7,自定义字段名称的@XStreamAlias注释,自定义转换器的@XStreamConverter(表示日期和其他自定义bean)。但是,甚至没有调用空值的自定义转换器。
我的目标是序列化对象的所有字段,包括null字段,我不需要解组XML。
I'm using XStream 1.4.7, @XStreamAlias annotation for custom field names, @XStreamConverter for custom converters (to represent dates and other custom beans). However, a custom converter for null values was not even called.My goal was to serialize all the fields of the object, including the null ones, I didn't need to unmarshal XML.
我设法做到了通过创建自定义ReflectionConverter。
我从XStream库扩展了ReflectionConverter并覆盖了doMarshal方法。我唯一改变的是为null info.values调用writeField方法:
I managed to do that by creating a custom ReflectionConverter.I extended ReflectionConverter from XStream library and overrode doMarshal method. The only thing I changed was calling writeField method for 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
}
};
之后,我创建了类似的xStream实例(将转换器注册到非常低的位置非常重要优先):
After that, I created xStream instance like that (it is very important to register your converter with very low priority):
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的解决方案
Thanks to Mark Nabours for his solution here
希望它有所帮助。有人找到了更好的解决方案吗?
Hope it helps. Has anyone found a better solution for this?
这篇关于XStream序列化空值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!