①在java代码Action中
在使用流的方法下载Excel的时候 经常会遇到如下错误:
java.lang.IllegalStateException: getOutputStream() has already been called for this response
详解:在tomcat5下jsp中出现此错误一般都是在jsp中使用了输出流(如输出图片验证码,文件下载等),没有妥善处理好的原因。
具体的原因就是
在tomcat中jsp编译成servlet之后在函数_jspService(HttpServletRequest request, HttpServletResponse response)的最后
有一段这样的代码
finally {
if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
}
这里是在释放在jsp中使用的对象,会调用response.getWriter()。
异常出现原因:这是因为在java中调用response.getOutputStream()方法 和 Servlet中调用 response.getWriter()相冲突造成的!所以会出现以上这个异常。
解决:在java中也使用PrintWriter(response.getWriter获取的是PrintWriter)就行了
如下:
/**
* @param response
* @param source 存放Excel文件本地路径
*/
private void download(HttpServletResponse response, File source){
Log.info("download-->1.source=" + source);
FileInputStream in = null;
//OutputStream out = null; //替换成PrintWriter
PrintWriter out = null;
try {
in = new FileInputStream(source);
//out = response.getOutputStream();
out = response.getWriter();//获取PrintWriter
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-disposition", new String(
("attachment; filename=" + source.getName()).getBytes(),
"ISO8859-1")); // 支持下载中文名称的文件
byte[] buffer = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) > 0) {
String temp = new String(buffer, "ISO8859-1"); //转码
//out.write(buffer, 0, len);
out.write(temp);
}
out.flush();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
②在使用jspsmart做文件下载时候,可能会遇到如下错误:
解决:在使用完out后应该 out.clear(); out=pageContext.pushBody();
如下:downloadFile.jsp
<%@ page import="com.aegon_cnooc.giss.util.Constants"%>
<%@ page import="com.jspsmart.upload.SmartUpload"%>
<%
String templateType = request.getParameter("templateType");
String fullFileName = null;
if("clause_one".equals(templateType)){
fullFileName = Constants.CLAUSE_DOC_ONE;//文件名全路径
}
try
{
if(fullFileName != null && fullFileName !="")
{
com.jspsmart.upload.SmartUpload su = new com.jspsmart.upload.SmartUpload();
su.initialize(pageContext);
su.setContentDisposition(null);
su.downloadFile(fullFileName);
}else
{
out.write("<a>" + "下载路径不能为空!" + "</a>");
}
}catch (Exception e)
{
out.write("<a>" + e.getMessage() + "</a>");
}finally{
if(out != null){
out.clear();
out=pageContext.pushBody();
}
}
%>
问题:今天在使用jspsmart做文件下载的时候,从一个jsp页面传参(文件路径filePath)到downloadFile.jsp进行文件下载,文件路径中带有中文,虽然统一了编码,但是downloadFile.jsp接受到的路径还是乱码,所以导致文件一直无法下载。最后网上找到如下方法解决:String fileName = new String(request.getParameter("fileName").getBytes("iso-8859-1"),"gb2312"); 倍感欣慰。这是问题又来了,发布到服务器上,无法下载。最后无奈只有改成流的方式做下载Excel了,好在问题及时解决了。后来又想了另外一种思路,还是使用jspsmart, 但是我把中文文件路径配置在常量文件(Constants.java)中,然后在downloadFile.jsp文件中引入 就解决了。