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

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

 

猜你喜欢

转载自weigang-gao.iteye.com/blog/2222451