文件下載後臺報錯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
相關文章
相關標籤/搜索