Java 已经为此响应调用了 getOutputStream()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1776142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
getOutputStream() has already been called for this response
提问by Southsouth
I google the error message getOutputStream() has already been called for this response
and many people said it is because of the space or newline after <%
or %>
, but in my code , there is no a space or a newline. I am using tomcat6 on linux.
我谷歌的错误消息getOutputStream() has already been called for this response
,很多人说,这是因为后面的空格或换行<%
或%>
,但在我的代码,没有一个空格或一个换行符。我在 linux 上使用 tomcat6。
<%@
page import="java.servlet.*,
javax.servlet.http.*,
java.io.*,
java.util.*,
com.lowagie.text.pdf.*,
com.lowagie.text.*"
%><%
response.setContentType("application/pdf");
Document document = new Document();
try{
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
PdfWriter.getInstance(document, buffer);
document.open();
PdfPTable table = new PdfPTable(2);
table.addCell("1");
table.addCell("2");
table.addCell("3");
table.addCell("4");
table.addCell("5");
table.addCell("6");
document.add(table);
document.close();
DataOutput dataOutput = new DataOutputStream(response.getOutputStream());
byte[] bytes = buffer.toByteArray();
response.setContentLength(bytes.length);
for(int i = 0; i < bytes.length; i++)
{
dataOutput.writeByte(bytes[i]);
}
}catch(DocumentException e){
e.printStackTrace();
}
%>
~
~
org.apache.jasper.JasperException: java.lang.IllegalStateException: getOutputStream() has already been called for this response
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:522)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:410)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
root cause
根本原因
java.lang.IllegalStateException: getOutputStream() has already been called for this response
org.apache.catalina.connector.Response.getWriter(Response.java:610)
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)
org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:188)
org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:118)
org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:77)
org.apache.jsp.Account.Domain.testPDF_jsp._jspService(testPDF_jsp.java:94)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
采纳答案by RealHowTo
Ok, you should be using a servletnot a JSP but if you really need to... add this directive at the top of your page:
好的,您应该使用servlet而不是 JSP,但如果您确实需要……在页面顶部添加此指令:
<%@ page trimDirectiveWhitespaces="true" %>
Or in the jsp-config section your web.xml
或者在 jsp-config 部分你的 web.xml
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<trim-directive-whitespaces>true</trim-directive-whitespaces>
</jsp-property-group>
</jsp-config>
Also flush
/close
the OutputStream
and return when done.
此外flush
/close
中OutputStream
和返回完成时。
dataOutput.flush();
dataOutput.close();
return;
回答by skaffman
The issue here is that your JSP is talking directly to the response OutputStream
. This technically isn't forbidden, but it's very much not a good idea.
这里的问题是您的 JSP 直接与响应对话OutputStream
。这在技术上并不是被禁止的,但这并不是一个好主意。
Specifically, you call response.getOutputStream()
and write data to that. Later, when the JSP engine tries to flush the response, it fails because your code has already "claimed" the response. An application can either call getOutputStream
or getWriter
on any given response, it's not allowed to do both. JSP engines use getWriter
, and so you cannot call getOutputStream
.
具体来说,您调用response.getOutputStream()
并向其写入数据。稍后,当 JSP 引擎尝试刷新响应时,它会失败,因为您的代码已经“声明”了响应。应用程序可以调用getOutputStream
或getWriter
任何给定的响应,但不允许两者兼而有之。JSP 引擎使用getWriter
,所以你不能调用getOutputStream
.
You should be writing this code as a Servlet, not a JSP. JSPs are only really suitable for textual output as contained in the JSP. You can see that there's no actual text output in your JSP, it only contains java.
您应该将此代码编写为 Servlet,而不是 JSP。JSP 仅真正适用于 JSP 中包含的文本输出。你可以看到你的 JSP 中没有实际的文本输出,它只包含 java.lang.
回答by Bozho
JSP is s presentation framework, and is generally not supposed to contain any program logic in it. As skaffman suggested, use pure servlets, or any MVC web framework in order to achieve what you want.
JSP 是表示框架,一般不应该在其中包含任何程序逻辑。正如 skaffman 建议的那样,使用纯 servlet 或任何 MVC Web 框架来实现您想要的。
回答by Igor
Here is what worked for me in similar case.
这是在类似情况下对我有用的方法。
After you finish writing into the Servlet
OutputStream
just call response.sendRedirect("yourPage.jsp");
. That would cause initiation of a new request from the browser, therefore avoid writing into the same output stream.
在您完成写入后Servlet
OutputStream
调用 just call response.sendRedirect("yourPage.jsp");
。这将导致浏览器发起新请求,因此避免写入相同的输出流。
回答by pnairn
Add the following inside the end of the try/catch to avoid the error that appears when the JSP engine flushes the response via getWriter()
在 try/catch 的末尾添加以下内容,避免 JSP 引擎通过 getWriter() 刷新响应时出现的错误
out.clear(); // where out is a JspWriter
out = pageContext.pushBody();
As has been noted, this isn't best practice, but it avoids the errors in your logs.
如前所述,这不是最佳实践,但可以避免日志中的错误。
回答by Wandile Nxumalo
This error was occuring in my program because the resultset was calling more columns to be displayed in the PDF Document than the database contained. For example, the table contains 30 fields but the program was calling 35 (resultset.getString(35))
这个错误发生在我的程序中,因为结果集调用了比包含的数据库更多的列来显示在 PDF 文档中。例如,该表包含 30 个字段,但程序调用了 35 个 (resultset.getString(35))
回答by Dan Torrey
I just experienced this problem.
我刚刚遇到了这个问题。
The problem was caused by my controller method attempting return type of String (view name)when it exits. When the method would exit, a second response stream would be initiated.
问题是由我的控制器方法在退出时尝试返回字符串类型(视图名称)引起的。当该方法退出时,将启动第二个响应流。
Changing the controller method return type to voidresolved the problem.
将控制器方法返回类型更改为void解决了问题。
I hope this helps if anyone else experiences this problem.
如果其他人遇到此问题,我希望这会有所帮助。
回答by michaelp
I had this problem only the second time I went to export. Once I added:
我第二次去出口时才遇到这个问题。一旦我添加:
response.getOutputStream().flush();
response.getOutputStream().close();
after the export was done, my code started working all of the time.
导出完成后,我的代码一直在工作。
回答by Daniel De León
I got the same error by using response.getWriter()
before a request.getRequestDispatcher(path).forward(request, response);
. So start works fine when I replace it by response.getOutputStream()
我response.getWriter()
在request.getRequestDispatcher(path).forward(request, response);
. 所以当我替换它时开始工作正常response.getOutputStream()
回答by Max
Use Glassfish 4.0 instead. This turns out to be a problem only in Glassfish 4.1.1 release.
请改用 Glassfish 4.0。事实证明,这仅是 Glassfish 4.1.1 版本中的问题。
PT-BR: Use o Glasfish 4.0. Este parece ser um problema apenas no Glassfish 4.1.1.
PT-BR:使用 o Glasfish 4.0。Este parece ser um problema apenas no Glassfish 4.1.1。