文件下载后台报错IllegalStateException: getOutputStream() has already been called

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

 1 <%@page language="java" contentType="text/html; charset=UTF-8"%>
 2 <%@page   import="java.util.*,java.io.*"%>
 3 <html>
 4 <head>
 5 <title>下载页面</title>
 6 </head>
 7 
 8 <body>
 9 <%
10 response.reset();  //记住要记住reset浏览器清空缓存,不然可能会出现乱码状况
11 
12 OutputStream o=response.getOutputStream(); 13 
14 ResourceBundle res = ResourceBundle.getBundle("test");    //test.properties
15 String XLSFile = res.getString("tempFileRootPath") + "/excel"; 16 File fileLoad=new File(XLSFile,"temp.xls"); 17 
18 if(fileLoad.exists()) { 19     response.setHeader("Content-disposition","attachment;filename="+URLEncoder.encode("filename文件名", "UTF-8")+".xls");//文件中文名UTF-8 20     response.setContentType("application/vnd.ms-excel"); 21     long fileLength=fileLoad.length(); 22     String length=String.valueOf(fileLength); 23     response.setHeader("Content_Length",length); 24     
25     FileInputStream in = new FileInputStream(fileLoad); 26     OutputStream o = null; 27     try{ 28     in = new FileInputStream(fileLoad); 29     
30     o = response.getOutputStream(); 31  out.clear(); 32 out = pageContext.pushBody();    // 
33     
34     int n=0; 35     byte b[]=new byte[500]; 36     
37     while((n=in.read(b))!=-1) { 38         o.write(b,0,n); 39  } 40  o.flush(); 41     
42     } catch (Exception e) { 43         out.write("文件导出异常" + e.toString()); 44     } finally { 45         if(in != null) { 46             try { 47  in.close(); 48             } catch(Exception e) {} 49  } 50         if(o != null) { 51             try { 52  o.close(); 53             } catch(Exception e) {} 54  } 55  } 56 } else { 57     out.write("未找到导出的临时文件"); 58 } 59 
60 %>
61 
62 </body>
63 </html>

缘由:html

 

在tomcat中jsp编译成servlet以后在函数_jspService(HttpServletRequest request, HttpServletResponse response)的最后
有一段这样的代码
finally {
   if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
  }
这里是在释放在jsp中使用的对象,会调用response.getWriter(),由于这个方法是和
response.getOutputStream()相冲突的!因此会出现以上异常 IllegalStateException: getOutputStream() has already been called。
jsp中出现此错误通常都是在jsp中使用了输出流(如输出图片验证码,文件下载等),没有妥善处理好的缘由。

解决方法:在使用完response.getOutputStream()的后面加上两句(标黄):java

out.clear(); out = pageContext.pushBody();

 附上javax.servlet.jsp.PageContext方法pushBody() 说明:api

public BodyContent pushBody()
Return a new BodyContent object, save the current "out" JspWriter, and update the value of the "out" attribute in the page scope attribute namespace of the PageContext.
Returns:
the new BodyContent
相关文章
相关标签/搜索