服务器端有xml流过来,为了解析,最初使用的方法是构建一个StringBuilder,在onMessage方法中不断append,最终形成一个完成的xml文件字符串(其中包含多个xml).最后使用DocumentBuilder来解析。这种做法在数据量小的时候可以维持,当一次传来大量xml,便会出现OOM。
改良后的方法使用边接收数据,边解析的异步方式,这样解析过的部分就可以丢掉而不继续占用内存。
准备工作,需要熟悉的API,
com.sun.jersey.api.client.Client : 用来构建提交Restful请求的客户端,可以通过其来设置请求的参数,比如是否异步调用,请求的header信息等等。
java.util.concurrent.Future: 接收异步请求返回的结果,可以用future.isDone(), future.isCancelled()来判断“是否返回”或“是否取消”等执行状态。
1 Future future = future =Client.create()2 .asyncResource(requestBean.getUrl())3 .entity(requestBean.getRequestBody(), "application/json")4 .post(InputStream.class);
com.google.common.base.Function :自定义callback方法,用来处理当一个返回完成时所得到的数据。Node是xml的基本元素,Void表示所定义的回掉无返回值。
1 Function callback = new Function() {2 publicVoid 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 callback) throwsException{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 = newDOMResult(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 }
原文:http://www.cnblogs.com/sengao/p/4928444.html