getOutputStream() has already been called for this response异常的原因和解决方法

转自http://blog.csdn.net/iron_wang/article/details/4204672

1.tomcat5下jsp出现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(),因为这个方法是和
response.getOutputStream()相冲突的!所以会出现以上这个异常。

然后当然是要提出解决的办法,其实挺简单的(并不是和某些朋友说的那样--
将jsp内的所有空格和回车符号所有都删除掉),

在使用完输出流以后调用以下两行代码即可:
out.clear();
out = pageContext.pushBody();

最后这里是一个输出彩色验证码例子(这样的例子几乎随处可见)
imag.jsp

<%@ page import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>
<%@ page import="java.io.OutputStream" %>
<%!
Color getRandColor(int fc,int bc){
Random random = new Random();
if(fc>255) fc=255;
if(bc>255) bc=255;
int r=fc+random.nextInt(bc-fc);
int g=fc+random.nextInt(bc-fc);
int b=fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}
%>
<%
try{
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
int width=60, height=20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
OutputStream os=response.getOutputStream();
Graphics g = image.getGraphics();
Random random = new Random();
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);

g.setFont(new Font("Times New Roman",Font.PLAIN,18));
g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x,y,x+xl,y+yl);
}
String sRand="";
for (int j=0;j<4;j++){
String rand=String.valueOf(random.nextInt(10));
sRand+=rand;
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
g.drawString(rand,13*j+6,16);
}
session.setAttribute("rand",sRand);
g.dispose();

ImageIO.write(image, "JPEG",os);
os.flush();
os.close();
os=null;
response.flushBuffer();
out.clear();
out = pageContext.pushBody();
}
catch(IllegalStateException e)
{
System.out.println(e.getMessage());
e.printStackTrace();
}%>


如有不足之处,欢迎斧正!

2

getOutputStream() has already been called for this response问题的解决
在jsp向页面输出图片的时候,使用response.getOutputStream()会有这样的提示:java.lang.IllegalStateException:getOutputStream() has already been called for this response,会抛出Exception

原因一:
JSP默认的输出流为PrintWriter ,即<% %>以外的东西所默认的输出方式,如果你尝试在JSP中使用ServletOutputStream就会引起错误.要嘛直接改用Servlet输出(复写service方法),要嘛删除除%><%中的任何东西
(包括HTML标签,空格,回车等东西)应该就可以。
对于这样的情况应该这样来解决,删除%><%之间的所有内容包括空格和换行符,最后也要消除空格和换行符,
最好再加上一句response.reset()。
原因二:

在J2EE的API参考里有这么个:

ServletResponse的getWriter()方法里会抛出这个异常,

IllegalStateException - if the getOutputStream method has already been called
for this response object

而它的getOutputStream()方法里会抛出这个异常.

IllegalStateException - if the getOutputStream method has already been called for this response object

并且两者的函数申明里都有这么样的一句
Either this method or getOutputStream() may be called to write the body, not both.
Either this method or getWriter() may be called to write the body, not both.


以上说明也解释了为什么在往页面中写入图片的时候要使用如下循环格式
OutputStream output=response.getOutputStream();
while((len=in.read(b)) >0)
{
output.write(b,0,len);

}
output.flush();
而不是把response.getOutputStream().write()放到循环体内

在页面中直接写:
<body bgcolor="#ffffff">
<h1>
<%
response.getOutputStream();
%>
</h1>
</body>
将会出现错误消息如下:
java.lang.IllegalStateException: getOutputStream() has already been called for this response
org.apache.catalina.connector.Response.getWriter(Response.java:604)
org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当你在项目中进行数据导出到Excel时,你可能会遇到"getOutputStream() has already been called for this response"的异常。这个异常原因可能是因为在你的代码中,同时调用了response.getOutputStream()和response.getWriter(),而根据Servlet规范,这两个方法不能同时调用。 在你提供的代码中,我可以看到你使用了@GetMapping注解来处理导出功能,并在方法参数中传入了HttpServletResponse对象。然后,你调用了ExcelPortUtil.excelPort()方法来进行数据写入Excel文件并返回。 为了解决"getOutputStream() has already been called for this response"异常,你可以按照下面的步骤进行调整: 1. 确保在你的代码中只调用response.getOutputStream()或response.getWriter()其中之一。 2. 检查你的ExcelPortUtil.excelPort()方法内部的实现,确保没有调用response.getOutputStream()或response.getWriter()。 3. 如果你的ExcelPortUtil.excelPort()方法内部确实需要使用response.getOutputStream(),那么你需要修改你的方法逻辑,确保在调用response.getOutputStream()之前没有调用response.getWriter()。 通过以上调整,你应该能够解决"getOutputStream() has already been called for this response"的异常。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [getOutputStream() has already been called for this response问题终极解决](https://blog.csdn.net/IT_51888_liang/article/details/122235797)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值