项目需求的缘故,需要把备份数据库表的文件及生成的SQL脚本打包下载(本想做成可以浏览目录的方式,不得,故采用该种方法),从网上找了点资料:下载采用了
org.apache.tools.zip.*;(
使用时把ant.jar放到classpath中,程序中使用import org.apache.tools.zip.*;
Apache Ant 下载地址:[url]http://ant.apache.org/[/url]
),因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
JSP下载打包文件及java.lang.IllegalStateException异常解决
最新推荐文章于 2023-03-28 17:55:52 发布