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
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
相关文章推荐
- jsp页面java+js实现文件下载(并附带解决下载文件名乱码问题-火狐浏览器正常访问)
- 【Servlet+Struts2】文件下载时抛出java.lang.IllegalStateException异常的解决方法
- Servlet.service() for servlet jsp threw exception java.lang.Il在jsp中使用jspsmartupload组件下载文件时将抛出异常的解决方案
- 上传下载文件实例异常:java.lang.IllegalStateException怎么解决?
- 关于打包自定义标签,并导入项目使用时,出现java.lang.NoClassDefFoundError: JspException异常,解决方法和注意事项!
- JAVA 根据Url把多文件打包成ZIP下载实例
- java代码实现打包多个文件下载功能
- 使用jspsmartupload上传文件抛出的java.lang.IllegalStateException异常
- java用io流打包下载文件
- 文件下载:java.lang.IllegalStateException: getOutputStream() has already been called for this response
- Java项目打包成Jar文件后图片不显示的问题解决
- 问题解决:java.lang.AbstractMethodError: javax.servlet.jsp.PageContext.getVariableResolver()Ljavax/servlet/jsp/el/VariableResolver;
- 文件能下载,但是报错:java.lang.IllegalStateException:getOutputStream() has already been called for this response
- eclipse中java工程打包成jar无法找到src资源文件路径的解决办法
- android 反编译打包出现java.lang.VerifyError错误的原因和解决
- 用java实现文件下载,提示java.lang.IllegalStateException: getOutputStream() has already been called for this response
- 使用HttpURLConnection下载文件时出现 java.io.FileNotFoundException彻底解决办法
- HTTP获取批量文件打包下载-java(自)
- springboot打包jar包找不到jsp文件以及在linux永久执行java -jar以及springboot的多环境配置
- JAVA代码实现下载单个文件,和下载打包文件