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));
}
}
给我 :
<student>
<name>toto</name>
<age>0</age>
</student>
有没有办法处理空值? 我的意思是 :
<student>
<name>toto</name>
<age>0</age>
<teacher></teacher>
</student>
如果我这样做是可能的
st.setTeacher("");
但如果教师为空则不行。
我试着用自定义转换器,但似乎空值不会被发送到转换器。
我正在使用XStream 1.4.7,@ XStreamAlias注释用于自定义字段名称,@ XStreamConverter用于自定义转换器(用于表示日期和其他自定义Bean)。 但是,空值的自定义转换器甚至没有被调用。 我的目标是序列化对象的所有字段,包括空字符,我不需要解组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
String teacher = "";
或优化一个:)
String teacher = StringUtils.EMPTY;
链接地址: http://www.djcxy.com/p/11365.html