①在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文件中引入 就解决了。