文件下载后台报错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>

原因:

在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()的后面加上两句(标黄):

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

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

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

猜你喜欢

转载自www.cnblogs.com/wrong/p/10420020.html