netty 系列之:netty 中常用的 xml 编码解码器
简介
在 json 之前,xml 是最常用的数据传输格式,虽然 xml 的冗余数据有点多,但是 xml 的结构简单清晰,至今仍然运用在程序中的不同地方,对于 netty 来说自然也提供了对于 xml 数据的支持。
netty 对 xml 的支持表现在两个方面,第一个方面是将编码过后的多个 xml 数据进行 frame 拆分,每个 frame 包含一个完整的 xml。另一方面是将分割好的 frame 进行 xml 的语义解析。
进行 frame 拆分可以使用 XmlFrameDecoder,进行 xml 文件内容的解析则可以使用 XmlDecoder,接下来我们会详细讲解两个 decoder 实现和使用。
XmlFrameDecoder
因为我们收到的是数据流,所以不确定收到的数据到底是什么样的,一个正常的 xml 数据可能会被拆分成多个数据 frame。
如下所示:
这是一个正常的 xml 数据,但是被拆分成为了三个 frame,所以我们需要将其合并成为一个 frame 如下:
还有可能不同的 xml 数据被分拆在多个 frame 中的情况,如下所示:
上面的数据需要拆分成为两个 frame:
拆分的逻辑很简单,主要是通过判断 xml 的分隔符的位置来判断 xml 是否开始或者结束。xml 中的分隔符有三个,分别是'<', '>' 和 '/'。
在 decode 方法中只需要判断这三个分隔符即可。
另外还有一些额外的判断逻辑,比如是否是有效的 xml 开始字符:
是否是注释:
是否是 CDATA 数据:
通过使用这些方法判断好 xml 数据的起始位置之后,就可以调用 extractFrame 方法将要使用的 ByteBuf 从原始数据中拷贝出来,最后放到 out 中去:
XmlDecoder
将 xml 数据拆分成为一个个 frame 之后,接下来就是对 xml 中具体数据的解析了。
netty 提供了一个 xml 数据解析的方法叫做 XmlDecoder,主要用来对已经是一个单独的 xml 数据的 frame 进行实质内容的解析,它的定义如下:
XmlDecoder 根据读取到的 xml 内容,将 xml 的部分拆分为 XmlElementStart,XmlAttribute,XmlNamespace,XmlElementEnd,XmlProcessingInstruction,XmlCharacters,XmlComment,XmlSpace,XmlDocumentStart,XmlEntityReference,XmlDTD 和 XmlCdata。
这些数据基本上覆盖了 xml 中所有可能出现的元素。
所有的这些元素都是定义在 io.netty.handler.codec.xml 包中的。
但是 XmlDecoder 对 xml 的读取解析则是借用了第三方 xml 工具包:fasterxml。
XmlDecoder 使用了 fasterxml 中的 AsyncXMLStreamReader 和 AsyncByteArrayFeeder 用来进行 xml 数据的解析。
这两个属性的定义如下:
decode 的逻辑是通过判断 xml element 的类型来分别进行不同数据的读取,最后将读取到的数据封装成上面我们提到的各种 xml 对象,最后将 xml 对象添加到 out list 中返回。
总结
我们可以借助 XmlFrameDecoder 和 XmlDecoder 来实现非常方便的 xml 数据解析,netty 已经为我们造好轮子了,我们就不需要再自行发明了。
本文已收录于 http://www.flydean.com/14-7-netty-codec-xml/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
版权声明: 本文为 InfoQ 作者【程序那些事】的原创文章。
原文链接:【http://xie.infoq.cn/article/50d5ee209f4880d08d23e2998】。文章转载请联系作者。
评论