由于客户的需要,WEB应用程序中有一项功能是要将数据库中的一张表导出成XML文件下载。最初采用的方案是一次将表中的所有数据读出,然后在内存中通过DOM完整地组织XML文档,完成以后通过转换将其输出到页面的响应流中。在数据量小时,这样的方案没有什么问题,但是当数据库中的数据比较多时,程序运行就产生了异常,查看Tomcat的日志,发现是内存溢出了。如何解决这个问题呢?
要从根本上解决这个问题,就要想办法降低内存的占用。显然这个方案中有两处占用了大量内存,一是将表中的数据全部读出保存于内存之中;二是在内存中将XML组织完整以后才向客户端输出。第一点很容易解决,采取每次读取一批数据分多次读取即可解决,而第二点,可以通过Java的stax解决。
以下是一段实现将大量数据形成XML文件并发送到客户端浏览器下载的例程,为了简明起见,数据是直接通过代码生成的而不是从数据库中读取的。该代码生成的XML约1G大小,经测试,未再发生内存溢出的错误。
package net.yanzhijun.edu;
import java.io.IOException;
import java.io.OutputStreamWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;