解析从服务器端返回的xml文件流

服务器端有xml流过来,为了解析,最初使用的方法是构建一个StringBuilder,在onMessage方法中不断append,最终形成一个完成的xml文件字符串(其中包含多个xml).最后使用DocumentBuilder来解析。这种做法在数据量小的时候可以维持,当一次传来大量xml,便会出现OOM。

改良后的方法使用边接收数据,边解析的异步方式,这样解析过的部分就可以丢掉而不继续占用内存。

准备工作,需要熟悉的API,

com.sun.jersey.api.client.Client : 用来构建提交Restful请求的客户端,可以通过其来设置请求的参数,比如是否异步调用,请求的header信息等等。

java.util.concurrent.Future<InputStream>: 接收异步请求返回的结果,可以用future.isDone(), future.isCancelled()来判断“是否返回”或“是否取消”等执行状态。

1 Future<InputStream> future = future = Client.create()
2            .asyncResource(requestBean.getUrl())
3            .entity(requestBean.getRequestBody(), "application/json")
4            .post(InputStream.class);

com.google.common.base.Function<Node,Void> :自定义callback方法,用来处理当一个返回完成时所得到的数据。Node是xml的基本元素,Void表示所定义的回掉无返回值。

1  Function<Node, Void> callback = new Function<Node, Void>() {
2              public Void apply(Node tradeNode) {
3                              //Process node and  customized logic etc.
4
5          }; 

javax.xml.stream.XMLOutputFactory: 构建工厂类来实例化XMLEventWriters 和 XMLStreamWriters。

javax.xml.parsers.DocumentBuilder: 创建DOM来解析XML数据源,这些数据源可以是InputStreams, Files, URLs, 以及SAX InputSources。

javax.xml.stream.XMLEventReader: 此类是用于解析 XML 事件的顶层接口。它提供查看下一个事件和返回属性接口中的配置信息的功能。可以通过一个while(event.hasNext())便利xml数据。

javax.xml.stream.XMLEventWriter: 生成XML文件的接口,此接口并不对xml的格式的合法性进行校验

javax.xml.namespace.QName.QName(String namespaceURI, String localPart): 构建一个xml 节点

 1     public void handleResponseStream(InputStream stream, Function<Node, Void> callback) throws Exception{
 2
 3         XMLOutputFactory outfac = XMLOutputFactory.newInstance();
 4         DocumentBuilder dombuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 5         XMLEventReader r = XMLInputFactory.newInstance().createXMLEventReader(stream);
 6         XMLEventWriter xew = null;
 7         DOMResult domresult = null;
 8         QName root = new QName("http://www.namespace.com", "tagstart");
 9
10         while(r.hasNext() ) {
11             XMLEvent e = r.nextEvent();
12             if(e.isStartElement() && root.equals(((StartElement)e).getName())) {
13                 domresult = new DOMResult(dombuilder.newDocument());
14                 xew = outfac.createXMLEventWriter(domresult);
15             }
16             if(xew != null) {
17                 xew.add(e);
18             }
19             if(e.isEndElement() && root.equals(((EndElement)e).getName())) {
20                 xew.close();
21                 callback.apply(domresult.getNode().getFirstChild());
22                 xew = null;
23             }
24         }
25     }
时间: 2024-10-07 14:19:21

解析从服务器端返回的xml文件流的相关文章

java 如何解析http请求返回的xml报文

xml报文解析方法有很多种,此处采用dom4j的方法. dom4j的jar包下载地址:https://dom4j.github.io/# 1.request.getInputStream()和new SAXReader().read(输入流): 返回的报文如下: <?xml version="1.0" encoding="UTF-8"?><CreateAccessKeyResponse> <CreateAccessKeyResult&g

dom方式解析4A服务返回的xml

4A服务客户端向6+1系统发送数据,分为两次发送,第一次发送获取token,加密后再发送一次,保证数据安全性. java解析xml一般有4种方法:DOM.SAX.JDOM.DOM4j 这里使用的是DOM import java.io.ByteArrayInputStream; import java.io.InputStream; import java.sql.Timestamp; import javax.xml.parsers.DocumentBuilder; import javax.x

错误集:js解析jQuery.post返回的xml之Could not find action or result

js里用jQuery.post去后台查询数据,返回的是xml格式的数据流. js代码: var params = ""; params = encodeURI(params); var url = "frame.query.action"; jQuery.post(url, params, function(xmlHttp){ var items = xmlHttp.getElementsByTagName("jg"); for (var i =

dom4j解析带命名空间的xml文件

文件内容如下 <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://WebXml.com.cn/"> <string>浙江</string> <string>杭州</string> <

用Pull解析Xml文件

1 public List<Person> DecodeXml(String filename) throws XmlPullParserException 2 { 3 // 获取当前程序的asset对象 4 AssetManager am = context.getAssets(); 5 6 List<Person> pList = new ArrayList<Person>(); 7 8 try { 9 10 //打开asset中文件为filename的文件,并以I

SAX方式解析XML文件的方法分析

SAX(Simple API for XML)SAX的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束.元素(element)开始与结束.文档(document)结束等地方时通知事件处理方法,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束.SAX解析方式适用于大型文档,因为他的解析是逐行进行不用像DOM中那样为所有节点创建对象,这样效率大大提高,所以虽然它不是W3C标准,但它却得到了广泛认可. 这是一个需要解析的XML文件: <?xml versio

解析XML文件之使用SAM解析器

XML是一种常见的传输数据方式,所以在开发中,我们会遇到对XML文件进行解析的时候,本篇主要介绍使用SAM解析器,对XML文件进行解析. SAX解析器的长处是显而易见的,那就是SAX并不须要将全部的文档都载入内存之后才进行解析.SAX是事件驱动机制的,也就是碰到元素节点.文本节点.文档节点的时候,都会触发一定的事件.我们仅仅须要在对应的回调事件里面进行对应的处理就能够了.由于这个特点,所以SAX解析占用的内存比較少.其它的解析方式,比方下一节要介绍的DOM解析器,则占用内存比較多.在解析比較小的

Android中pull解析XML文件的简单使用

首先,android中解析XML文件有三种方式,dom,sax,pull 这里先讲pull,稍候会说SAX和DOM pull是一种事件驱动的xml解析方式,不需要解析整个文档,返回的值是数值型,是推荐的解析方式 看代码: XML文件 <?xml version="1.0" encoding="UTF-8"?> <persons> <person id="23"> <name>孙洋洋</name

XML文件解析-DOM4J方式和SAX方式

最近遇到的工作内容都是和xml内容解析相关的. 1图片数据以base64编码的方式保存在xml的一个标签中,xml文件通过接口的方式发送给我,然后我去解析出图片数据,对图片进行进一步处理. 2.xml内容保存在blob字段中,然后jdbc读取blob字段获取xml内容进行解析. 解析的方法挺简单的,网上有很多种,主要有SAX,DOM4J等. 先来揭晓一下DOM4J是如何解析xml文件的,话不多少,直接上码. /** * 获取xml文件绝对路径 */ private String getFileP