我有这个json的例子:
{
"rows": [
{
"anaid": "1",
"anaint": "123",
"anastring": "-"
},
{
"anaid": "2",
"anaint": "-",
"anastring": "Hello World"
},
{
"anaid": "3",
"anaint": "-",
"anastring": "-"
}
]
}
我班上的测试是:
我的java代码:
XStream xstream = new XStream(new JettisonMappedXmlDriver());
xstream.alias("rows", Test.class);
ArrayList<Test> product = (ArrayList<Test>) xstream.fromXML(json);
因此字符“ - ”是我的json的空值。我无法更改代码来创建json,但我会处理“ - ”null值以正确使用我的xStream解析器。
答案 0 :(得分:0)
使用自定义转换器。教程here
答案 1 :(得分:0)
根据XStream的文档和邮件列表,编组输出中不包含空值 - 可能是一种约定。
discussion帮助我弄清楚如何展示它们。简而言之,诀窍是Varun所说的:一个自定义转换器,用于扩展默认的ReflectionConverter。我们的想法是停止忽略空值事件并将它们写入输出。
以下是对我如何运作的详细解释。不幸的是我无法分发最终解决方案;我希望以下解锁很多,甚至导致在主树中集成。
<强>配方强>
以下是我的解决方案的要点,基于[1]和XStream 1.4.2:
com.thoughtworks.xstream.converters.reflection.ReflectionConverter
类。doMarshal
/ 3方法。原始方法忽略空事件,因此不写入任何内容。新方法应该只接受那些事件并写下想要的东西(一个空节点,一个自闭节点)。writeField
/ 5方法以写入空值节点。写什么取决于想要什么,应该委托给编写者对象。com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriter
和com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper
类以提供自定义编写器。写下空值节点需要一种方法。有关方法的更多细节
例如,可以扩展一个带有XStream的编写器并实现一个额外的接口:
// Context of "MyReflectionConverter"'s doMarshal method.
void writeField(...)
if (newObj == null) {
NullExtendedHierarchicalStreamWriterHelper.emptyNode(
writer.underlyingWriter(),
aliasName != null ? aliasName:
mapper.serializedMember(source.getClass(), fieldName),
fieldType);
}
else { // Rest of the original writeField method
}
}
界面位于NullExtendedHierarchicalStreamWriter
,向emptyNode
添加ExtendedHierarchicalStreamWriter
/ 2方法。此方法将空值写为自闭节点(例如,对于XML <int value="num"/>
,意味着num
是一个空整数)。上面的代码段使用帮助器NullExtendedHierarchicalStreamWriterHelper
获取此作者的实例,该帮助器本身是ExtendedHierarchicalStreamWriterHelper
的简单扩展。请注意,传递给帮助程序的编写器是writer.underlyingWriter()
,因为编写器被包装并且包装器不实现接口的null扩展 - 这意味着我的解决方案仍然是一个黑客攻击,直到进行更深入的集成。
转换器的注册通常以这种方式完成:
serializer = new XStream(new MyStreamDriver());
MyReflectionConverter reflectionConverter = new
MyReflectionConverter(serializer.getMapper(),
serializer.getReflectionProvider());
serializer.registerConverter(reflectionConverter, XStream.PRIORITY_VERY_LOW);
Here是上述自定义反射转换器与原始代码的差异。请考虑这是一个不属于主树的扩展,并且它比原始代码测试的要少得多。到目前为止,它通过了测试套件的案例。
答案 2 :(得分:0)
对我来说,简单的方法是获取源代码,复制ReflexionConverted类和方法public void marshal(Object original,final HierarchicalStreamWriter writer,final MarshallingContext context)...
你有:reflectionProvider.visitSerializableFields(source, new ReflectionProvider.Visitor() {
public void visit(String fieldName, Class fieldType, Class definedIn, Object newObj) {
if (newObj != null) {
...
complete the else method with your code...for example:
} else {
Object obj = new String("");
writeField(fieldName, fieldType, definedIn, obj);
seenFields.add(fieldName);
}
}
}