getOutputStream() has already been called for this response的解决方法

轻量级J2EE企业应用实战》一书的第2章有一个使用SerlvetResponse输出图像的例子,代码如下:

<%
  BufferedImage image 
= new BufferedImage(400400 , BufferedImage.TYPE_INT_RGB);
  Graphics g 
=
 image.getGraphics();
  g.fillRect(
0,0,400,400
);
  g.setColor(
new Color(255,0,0
));  
  g.fillArc(
20,20,100,100,30,120
);
  g.setColor(
new Color(0,255,0
));
  g.fillArc(
20,20,100,100,150,20
);
  g.setColor(
new Color(0,0,255
));
  g.fillArc(
20,20,100,100,270,120
);
  g.setColor(
new Color(0,0,0
));
  g.drawString(
"red:climb" , 30080
);
  g.drawString(
"green:swim"300120
);
  g.drawString(
"blue:jump"300160
);
  ImageIO.write(image, 
"bmp"
, response.getOutputStream());
  
//
out.clear();
  
//out = pageContext.pushBody();

%>

在Tomcat下运行时抛出如下异常:

    at org.apache.catalina.connector.Response.getWriter(Response.java:601)
    at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:196 )
    at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:
125
)
    at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:
118
)
    at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:
185
)
    at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:
116
)
    at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:
76
)
    
at org.apache.jsp.pages.drawImage_jsp._jspService(drawImage_jsp.java:84)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98 )
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:
803
)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:
328
)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:
315
)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:
265
)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:
803
)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:
269
)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
188
)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:
210
)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:
174
)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:
127
)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:
117
)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:
108
)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:
151
)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:
870
)
    at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:
665
)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:
528
)
    at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:
81
)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:
685
)
    at java.lang.Thread.run(Thread.java:
595)

查看转换后的JSP代码,发现第84行如下(绿色高亮处):

  public void  _jspService(HttpServletRequest request, HttpServletResponse response)
        
throws java.io.IOException, ServletException 
{

    JspFactory _jspxFactory 
= null
;
    PageContext pageContext 
= null
;
    HttpSession session 
= null
;
    ServletContext application 
= null
;
    ServletConfig config 
= null
;
    JspWriter out 
= null
;
    Object page 
= this
;
    JspWriter _jspx_out 
= null
;
    PageContext _jspx_page_context 
= null
;


    
try 
{
      _jspxFactory 
=
 JspFactory.getDefaultFactory();
      response.setContentType(
"text/html; charset=UTF-8"
);
      pageContext 
= _jspxFactory.getPageContext(this
, request, response,
                  
nulltrue8192true
);
      _jspx_page_context 
=
 pageContext;
      application 
=
 pageContext.getServletContext();
      config 
=
 pageContext.getServletConfig();
      session 
=
 pageContext.getSession();
      out 
=
 pageContext.getOut();
      _jspx_out 
=
 out;

      out.write(
"\r\n"
);
      out.write(
"\n"
);
      out.write(
"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");

      out.write("<html>\n");
      out.write(
"<head>\n"
);
      out.write(
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n"
);
      out.write(
"<title>Draw Image</title>\n"
);
      out.write(
"</head>\n"
);
      out.write(
"<body>\n"
);
      out.write(
"\r\n"
);

  BufferedImage image 
= new BufferedImage(400400
, BufferedImage.TYPE_INT_RGB);
  Graphics g 
=
 image.getGraphics();
  g.fillRect(
0,0,400,400
);
  g.setColor(
new Color(255,0,0
));  
  g.fillArc(
20,20,100,100,30,120
);
  g.setColor(
new Color(0,255,0
));
  g.fillArc(
20,20,100,100,150,20
);
  g.setColor(
new Color(0,0,255
));
  g.fillArc(
20,20,100,100,270,120
);
  g.setColor(
new Color(0,0,0
));
  g.drawString(
"red:climb" , 30080
);
  g.drawString(
"green:swim"300120
);
  g.drawString(
"blue:jump"300160
);
  ImageIO.write(image, 
"bmp"
, response.getOutputStream());
  
//
out.clear();
  
//out = pageContext.pushBody();


      out.write(
"\r\n");
      out.write(
"</body>\n"
);
      out.write(
"</html>"
);
    }
 catch (Throwable t) {
      
if (!(t instanceof SkipPageException))
{
        out 
=
 _jspx_out;
        
if (out != null && out.getBufferSize() != 0
)
          out.clearBuffer();
        
if (_jspx_page_context != null
) _jspx_page_context.handlePageException(t);
      }

    }
 finally {
      
if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }

我们看到在JSP页面释放资源的时候,调用了ServetResponse.getWriter()方法,之后程序即抛出异常了,查看Servlet的API发现问题: 
public java.io.PrintWriter getWriter()
throws java.io.IOException
Returns a PrintWriter object that can send character text to the client. The PrintWriter uses the character encoding returned by getCharacterEncoding(). If the response's character encoding has not been specified as described in getCharacterEncoding (i.e., the method just returns the default value ISO-8859-1), getWriter updates it to ISO-8859-1.

Calling flush() on the PrintWriter commits the response.

Either this method or getOutputStream() may be called to write the body, not both.

 

Returns:
a PrintWriter object that can return character data to the client
Throws:
UnsupportedEncodingException - if the character encoding returned by getCharacterEncoding cannot be used
java.lang.IllegalStateException - if the getOutputStream method has already been called for this response object
java.io.IOException - if an input or output exception occurred
See Also:
getOutputStream(), setCharacterEncoding(java.lang.String)
如API所言,由于ServletResponse.getOutputStream()方法和该方法都有可能被调用,来输出JSP页面的内容,如果其中的一个方法被调用了,再调用另一个方法就会抛出异常。

解决方法如下:

将JSP页面的最后两行代码的注释去掉,这两行代码的作用如下:

out.clear():清空缓存的内容。

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

·返回一个新的BodyContent(代表一个HTML页面的BODY部分内容)
·保存JspWriter实例的对象out
·更新PageContext的out属性的内容

  • 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、付费专栏及课程。

余额充值