解析从服务器端返回的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()来判断“是否返回”或“是否取消”等执行状态。


    //补充对连接服务和读取数据时候timeout的设定

   Integer timeout = 60000; //60secs
    ClientConfig cc = new DefaultClientConfig();
    cc.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT, timeout);
    cc.getProperties().put(ClientConfig.PROPERTY_READ_TIMEOUT, timeout);


1
Future<InputStream> future = Client.create(cc) 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的格式的合法性进行校验
Open Declaration 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     }

 

 

posted on 2015-11-01 19:30  windrainer  阅读(2354)  评论(0编辑  收藏  举报

导航