已为此响应调用 getOutputStream()
我用谷歌搜索错误消息getOutputStream()已经被调用用于此响应
很多人说这是因为 <%
或 %>
之后的空格或换行符,但在我的代码中,没有空格或换行符。我在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)
根本原因
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)
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.
<%@
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(17)
好的,您应该使用 servlet 而不是 JSP,但如果您确实需要...在页面顶部添加此指令:
或者在 web.xml 的 jsp-config 部分中
添加< code>flush/
close
OutputStream
并在完成后返回。Ok, you should be using a servlet not a JSP but if you really need to... add this directive at the top of your page:
Or in the jsp-config section your web.xml
Also
flush
/close
theOutputStream
and return when done.这里的问题是您的 JSP 直接与响应
OutputStream
对话。从技术上讲,这并没有被禁止,但这并不是一个好主意。具体来说,您调用response.getOutputStream() 并向其中写入数据。稍后,当 JSP 引擎尝试刷新响应时,它会失败,因为您的代码已经“声明”了响应。应用程序可以对任何给定响应调用
getOutputStream
或getWriter
,但不允许同时执行这两种操作。 JSP 引擎使用getWriter
,因此您无法调用getOutputStream
。您应该将此代码编写为 Servlet,而不是 JSP。 JSP 仅真正适合 JSP 中包含的文本输出。您可以看到 JSP 中没有实际的文本输出,它只包含 java.sql.
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.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 callgetOutputStream
orgetWriter
on any given response, it's not allowed to do both. JSP engines usegetWriter
, and so you cannot callgetOutputStream
.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.
我第二次去出口时才遇到这个问题。一旦我添加:
导出完成后,我的代码就开始一直工作。
I had this problem only the second time I went to export. Once I added:
after the export was done, my code started working all of the time.
在 try/catch 末尾添加以下内容,以避免 JSP 引擎通过 getWriter() 刷新响应时出现的错误
正如已经指出的,这不是最佳实践,但它避免了日志中的错误。
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()
As has been noted, this isn't best practice, but it avoids the errors in your logs.
我刚刚经历过这个问题。
该问题是由我的控制器方法在退出时尝试返回 String(视图名称) 类型引起的。当该方法退出时,将启动第二个响应流。
将控制器方法返回类型更改为 void 解决了该问题。
如果其他人遇到这个问题,我希望这会有所帮助。
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 void resolved the problem.
I hope this helps if anyone else experiences this problem.
这是在类似情况下对我有用的方法。
完成写入
Servlet
OutputStream
后,只需调用response.sendRedirect("yourPage.jsp");
。这将导致浏览器发起新请求,因此避免写入同一输出流。Here is what worked for me in similar case.
After you finish writing into the
Servlet
OutputStream
just callresponse.sendRedirect("yourPage.jsp");
. That would cause initiation of a new request from the browser, therefore avoid writing into the same output stream.JSP 是表示框架,通常不应该包含任何程序逻辑。正如 skaffman 建议的那样,使用纯 servlet 或任何 MVC Web 框架来实现您想要的目标。
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.
我的程序中出现此错误是因为结果集调用的 PDF 文档中显示的列数多于数据库包含的列数。例如,表包含 30 个字段,但程序调用 35 (resultset.getString(35))
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))
我在
request.getRequestDispatcher(path).forward(request, response);
之前使用response.getWriter()
遇到了同样的错误。因此,当我用response.getOutputStream()
替换它时,start 工作正常I got the same error by using
response.getWriter()
before arequest.getRequestDispatcher(path).forward(request, response);
. So start works fine when I replace it byresponse.getOutputStream()
我遇到了同样的问题,我只需添加“return;”就解决了在 FileInputStream 的末尾。
这是我的 JSP
I got the same problem, and I solved just adding "return;" at the end of the FileInputStream.
Here is my JSP
我没有使用JSP,但当我通过调用PrintWriter的flush()方法或return语句设置响应返回JSON对象时,我遇到了类似的错误。之前的答案即将 return-statement 包装到 try-block 中,效果如下:错误消失了,因为 return-statement 使方法忽略 try-catch 下面的所有代码,特别是在我的情况下,行redirectStrategy.sendRedirect(request,response,destination_addr_string)这似乎修改了导致错误的已提交响应。在我的例子中,更简单的解决方案只是删除该行并让客户端应用程序负责重定向。
I didn't use JSP but I had similar error when I was setting response to return JSON object by calling PrintWriter's flush() method or return statement. Previous answer i.e wrapping return-statement into a try-block worked kind of: the error disappeared because return-statement makes method to ignore all code below try-catch, specifically in my case, line redirectStrategy.sendRedirect(request, response, destination_addr_string) which seem to modify the already committed response that causes the error. The simpler solution in my case was just to remove the line and let client app to take care of the redirection.
我遇到了同样的问题,出现这个问题是因为如果您使用 getWriter()/getOutputStream() 使用多个写入器/输出流,Java 会给出错误。
对我来说,问题是我正在使用 @Logging 和 @RestLogging,避免在调用 API 时使用额外的注释。
I faced the same issue, this issue occurs because Java gives an error if you use multiple writer/output stream using getWriter()/getOutputStream().
For me the issue was I was using @Logging and @RestLogging, avoid using extra annotation while calling the API.
就我而言,我使用 out 对象来打印代码,它显示类似 getOutputStream() 已调用响应的错误。
为了解决此错误,我正在初始化另一个 PrintWriter 对象 out1 并使用它来打印运行良好的代码。
例如。
前:
out.println("错误");
后:
PrintWriter out1 = response.getWriter();
out1.println("成功");
In my case I am using the out object for printing the code It shows the error like getOutputStream() has already called for the response.
For resolving this error, I am initializing another PrintWriter object out1 and use that for printing the code That's working perfectly.
Eg.
Before:
out.println("Error");
After:
PrintWriter out1 = response.getWriter();
out1.println("Success");
就我而言,我曾经在 Jboss 7.4.0 上遇到 ServletOutputStreamException() UTC010029 Stream is close 问题。当我在写入输出流之前调用 os.flush() 即 os = response.getOutputStream() 时,它被清除了[响应是 HttpServletOutputStream 的对象]。这里的一些评论是救星。 +1伙计们。
In my case I used to get ServletOutputStreamException() UTC010029 Stream is closed issue on Jboss 7.4.0. It got cleared when I called os.flush() i.e os = response.getOutputStream() before I write to the outputstream [response is an object of HttpServletOutputStream]. Some of the comments here were a life saver. +1 guys.
在某些情况下,当您
在声明或使用
RequestDispatcher
之后再声明时,会发生这种情况。我在创建一个简单的
LoginServlet
时遇到了类似的问题,我在声明RequestDispatcher
后定义了Writer
。尝试在
RequestDispatcher
类之前定义Writer
类对象。In some cases this case occurs when you declare
after declaring or using
RequestDispatcher
.I encountered this similar problem while creating a simple
LoginServlet
, where I have definedWriter
after declaringRequestDispatcher
.Try defining
Writer
class object beforeRequestDispatcher
class.这个答案与其他答案不同,也许这会对某人有所帮助。
如果在将响应发送回客户端时出现问题,请将您的应用程序视为服务器,然后检查相应类的所有Getter方法是否已实现类属性。
我遇到了同样的问题,就我而言,上述步骤可以帮助我解决问题。
不要将其视为最终解决方案,而应将其视为解决方案/最佳实践/除精确解决方案之外的任何其他解决方案的一步。
This answer would be different from other answers, May be this would help someone.
If issue was seen while sending response back to client, Considering your application as server then check Getter methods were implemented for the respective class with all the class attributes.
I experience this same issue, In my case the above steps helps me resolve the issue.
Don't consider this as final solution, Consider it as one step forward to solution / Best practice / anything other than exact solution.
请改用 Glassfish 4.0。事实证明,这只是 Glassfish 4.1.1 版本中的一个问题。
Use Glassfish 4.0 instead. This turns out to be a problem only in Glassfish 4.1.1 release.