xStream JSON - 如何处理空值
我有这个 json 示例:
{
"rows": [
{
"anaid": "1",
"anaint": "123",
"anastring": "-"
},
{
"anaid": "2",
"anaint": "-",
"anastring": "Hello World"
},
{
"anaid": "3",
"anaint": "-",
"anastring": "-"
}
]
}
在我的类 Test 中,其中有:
- int anaid
- int anaint
- String anastring
我的 java 代码:
XStream xstream = new XStream(new JettisonMappedXmlDriver());
xstream.alias("rows", Test.class);
ArrayList<Test> product = (ArrayList<Test>) xstream.fromXML(json);
所以字符“-”是我的 json 的空值。我无法更改代码来创建 json,但我会处理“-”空值以正确使用我的 xStream 解析器。
I've this json example:
{
"rows": [
{
"anaid": "1",
"anaint": "123",
"anastring": "-"
},
{
"anaid": "2",
"anaint": "-",
"anastring": "Hello World"
},
{
"anaid": "3",
"anaint": "-",
"anastring": "-"
}
]
}
where in my class Test are:
- int anaid
- int anaint
- String anastring
My java code:
XStream xstream = new XStream(new JettisonMappedXmlDriver());
xstream.alias("rows", Test.class);
ArrayList<Test> product = (ArrayList<Test>) xstream.fromXML(json);
So the character "-" is the null value for my json. I can't change the code to create json, but I would handling the "-" null value to use correctly my xStream parser.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
根据 XStream 的文档和邮件列表,空值不包含在编组输出中——这可能是一种约定。
讨论帮助我弄清楚了如何显示它们。简而言之,窍门就是 Varun 所说的:自定义转换器,用于扩展默认的 ReflectionConverter。这个想法是停止忽略空值事件并将它们写入输出。
这是关于它如何对我起作用的详细解释。不幸的是我无法分发最终的解决方案;我希望以下内容能够解锁许多内容,甚至导致在主树中的集成。
食谱
这是我的解决方案的要点,基于[1] 和 XStream 1.4.2:
doMarshal
/3方法。原始方法忽略空事件,因此不写入任何内容。新方法应该只获取这些事件并写入所需的内容(空节点、自关闭节点)。writeField
/5 方法来写入空值节点。写什么取决于想要什么,并且应该委托给 writer 对象。有关该方法的更多详细信息
例如,可以扩展 XStream 提供的编写器并实现一个额外的接口:
该接口位于
NullExtendedHierarchicalStreamWriter
中,它添加了一个emptyNode/2 方法到
ExtendedHierarchicalStreamWriter
。此方法将空值写入自关闭节点(例如,对于 XML
,意味着num
是空整数)。上面的代码片段使用帮助器NullExtendedHierarchicalStreamWriterHelper
获取此编写器的实例,它本身是ExtendedHierarchicalStreamWriterHelper
的简单扩展。请注意,传递给帮助器的编写器是 writer.underlyingWriter(),因为编写器被包装并且包装器没有实现接口的 null 扩展——这意味着我的解决方案仍然是一个 hack,直到进行了更深入的整合。转换器的注册通常是这样完成的:
这里是上述自定义反射转换器与原始代码的差异。请考虑,这是一个扩展,不属于主树的一部分,并且它比原始代码经过的测试要少得多。迄今为止,它已经通过了测试套件的案例。
According to XStream's documentation and mailing list, null values are not included in the marshaling output---perhaps as a convention.
A discussion helped me figure out how to display them. In short, the trick is what Varun said: A custom converter, to extend the default ReflectionConverter. The idea is to stop ignoring null value events and write them to the output.
Here is a detailed explanation on how that worked for me. Unfortunately I cannot distribute the final solution; I hope the following unlocks many, or even leads to integration in the main tree.
Recipe
Here is the gist of my solution, based on [1] and XStream 1.4.2:
com.thoughtworks.xstream.converters.reflection.ReflectionConverter
class.doMarshal
/3 method. The original method ignores null events and so writes nothing. The new method should just take those events and write what is wanted (an empty node, a self-closing node).writeField
/5 method to write the null value nodes. What to write depends of what is wanted, and should be delegated to a writer object.com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriter
andcom.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper
classes to provide a custom writer. A single method is needed to write down a null value node.More detail on the approach
For example, one can extend a writer provided with XStream and implement an extra interface:
The interface is here
NullExtendedHierarchicalStreamWriter
which adds anemptyNode
/2 method toExtendedHierarchicalStreamWriter
. This method writes a null value as a self-closing node (e.g. for XML<int value="num"/>
, meaningnum
is a null integer). The above snippet gets an instance of this writer using a helperNullExtendedHierarchicalStreamWriterHelper
, itself a simple extension ofExtendedHierarchicalStreamWriterHelper
. Note that the writer passed to the helper iswriter.underlyingWriter()
, as writers are wrapped and the wrapper does not implement the null extension of the interface---this means my solution remains a hack until a deeper integration is done.Registration of the converter is typically done this way:
Here is a diff of the above custom reflection converter, against the original code. Please consider that this is an extension that is not part of the main tree, and it is much less tested than the original code. To date it passes the cases of a test suite.
对我来说,简单的方法是获取源代码,复制 ReflexionConverted 类并在方法中 public void marshal(Object original, Final HierarchicalStreamWriter writer, Final MarshallingContext context) ...
你有:
For me the easy way is to get the source code, copy the ReflexionConverted class and in the method public void marshal(Object original, final HierarchicalStreamWriter writer, final MarshallingContext context)...
you have:
使用自定义转换器。教程此处
Use a custom converter. Tutorial here