您的位置:首页 > 编程语言 > Java开发

JSP下载打包文件及java.lang.IllegalStateException异常解决

2012-05-14 16:09 726 查看
项目需求的缘故,需要把备份数据库表的文件及生成的SQL脚本打包下载(本想做成可以浏览目录的方式,不得,故采用该种方法),从网上找了点资料:下载采用了

org.apache.tools.zip.*;(

使用时把ant.jar放到classpath中,程序中使用import org.apache.tools.zip.*;

Apache Ant 下载地址:http://ant.apache.org/

),因JDK本身的java.util.zip有中文乱码问题;

代码如下:

<%@page import="java.util.*"%>

<%@page import="java.io.*"%>

<%@page import="org.apache.commons.lang.*" %>

<%@page import="com.cupdata.util.*" %>

<%@page import="org.apache.tools.zip.*" %>

<%

//读取文件集合

ArrayList<File> files = FileUtil.getFiles(savePath);//传入保存文件的路径savePath,并读取文件集合,代码就不写了,呵呵

//设置浏览器显示的内容类型为Zip

response.setContentType("application/zip");

//设置内容作为附件下载,并且名字为:export.zip

response.setHeader("Content-Disposition", "attachment; filename= export.zip");

//装饰输出流为Zip输出流

ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());

//读取文件的缓存

byte[] buffer = new byte[1024];

int length = 0;

for (File file:files) {

//向Zip中添加一个条目(也就是添加一个文件)

zos.putNextEntry(new ZipEntry(file.getPath()));

//读取文件数据写到ZipOutputStream

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));

while((length = bis.read(buffer))!=-1){

zos.write(buffer);

}

//关闭zip条目

zos.closeEntry();

bis.close();

}

zos.flush();

zos.close();

out.clear();

out = pageContext.pushBody();

%>

最后两句 out.clear(); out = pageContext.pushBody(); ,如果不加,由于项目采用的框架在请求返回中有调用response.getWriter().write(out),导致抛异常

java.lang.IllegalStateException: getOutputStream() has already been called for this response;

网上查了查,说是getWriter和getgetOutputStream不能同时用,又从网上下了Servlet规范,确认了下:

public ServletOutputStream getOutputStream()

throws IOException

Returns a ServletOutputStream suitable for writing binary data in the

response. The servlet container does not encode the binary data.

Calling flush() on the ServletOutputStream commits the response. Either this

method or getWriter() may be called to write the body, not both.

Returns: a ServletOutputStream for writing binary data

Throws:

IllegalStateException - if the getWriter method has been called on this

response

IOException - if an input or output exception occurred

看来确实如此;

那么这两句话是什么意思呢?

JSP容器在处理完成请求后会调用releasePageContext方法释放所有的PageContextObject,并且同时调用getWriter方法。由于getWriter方法与在JSP页面中使用流相关的getOutputStream方法冲突,所以会造成这种异常;

pushBody()的作用是保存当前的out对象,并更新PageContext中Page范围内Out对象;

将out对象重置,从而解决了冲突;

注:本文主要参考以下四篇博文:
http://www.pin5i.com/showtopic-23328.html http://alex295111.iteye.com/blog/519004 http://xiangxingchina.iteye.com/blog/748233 http://xiaodiandian.iteye.com/blog/662995
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐