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(),很多人说这是因为在<%或%>之后的空间或换行,但是在我的代码中,没有空格或换行符。我正在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)
11 个解决方案
#1
43
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:
好的,您应该使用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.
也刷新/关闭输出流,完成后返回。
dataOutput.flush();
dataOutput.close();
return;
#2
32
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。
#3
7
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.
如前所述,这不是最佳实践,但它避免了日志中的错误。
#4
3
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.
将控制器方法返回类型改为void,解决了问题。
I hope this helps if anyone else experiences this problem.
我希望这能帮助其他人遇到这个问题。
#5
3
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.
导出完成后,我的代码开始一直工作。
#6
3
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后,只需调用response.sendRedirect(“yourPage.jsp”);这将导致来自浏览器的新请求的启动,因此避免写入到相同的输出流中。
#7
2
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是s表示框架,通常不应该包含任何程序逻辑。正如skaffman所建议的,使用纯servlet或任何MVC web框架来实现您想要的。
#8
0
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))
这个错误出现在我的程序中,因为resultset调用的PDF文档中显示的列比包含的数据库多。例如,该表包含30个字段,但程序调用了35个字段(resultset.getString(35))
#9
0
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()
在request.getRequestDispatcher(path)之前,我使用response.getWriter()得到了相同的错误。(请求、响应);。所以当我用response.getOutputStream()替换它时,就可以开始工作了
#10
0
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.
使用o玻璃鱼4.0。没有玻璃鱼,就不会有问题。
#11
-1
In some cases this case occurs when you declare
在某些情况下,这种情况发生在您声明时
Writer out=response.getWriter
after declaring or using RequestDispatcher
.
声明或使用RequestDispatcher之后。
I encountered this similar problem while creating a simple LoginServlet
, where I have defined Writer
after declaring RequestDispatcher
.
我在创建一个简单的LoginServlet时遇到了类似的问题,我在声明RequestDispatcher之后定义了Writer。
Try defining Writer
class object before RequestDispatcher
class.
尝试在RequestDispatcher类之前定义Writer类对象。
#1
43
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:
好的,您应该使用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.
也刷新/关闭输出流,完成后返回。
dataOutput.flush();
dataOutput.close();
return;
#2
32
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。
#3
7
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.
如前所述,这不是最佳实践,但它避免了日志中的错误。
#4
3
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.
将控制器方法返回类型改为void,解决了问题。
I hope this helps if anyone else experiences this problem.
我希望这能帮助其他人遇到这个问题。
#5
3
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.
导出完成后,我的代码开始一直工作。
#6
3
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后,只需调用response.sendRedirect(“yourPage.jsp”);这将导致来自浏览器的新请求的启动,因此避免写入到相同的输出流中。
#7
2
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是s表示框架,通常不应该包含任何程序逻辑。正如skaffman所建议的,使用纯servlet或任何MVC web框架来实现您想要的。
#8
0
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))
这个错误出现在我的程序中,因为resultset调用的PDF文档中显示的列比包含的数据库多。例如,该表包含30个字段,但程序调用了35个字段(resultset.getString(35))
#9
0
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()
在request.getRequestDispatcher(path)之前,我使用response.getWriter()得到了相同的错误。(请求、响应);。所以当我用response.getOutputStream()替换它时,就可以开始工作了
#10
0
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.
使用o玻璃鱼4.0。没有玻璃鱼,就不会有问题。
#11
-1
In some cases this case occurs when you declare
在某些情况下,这种情况发生在您声明时
Writer out=response.getWriter
after declaring or using RequestDispatcher
.
声明或使用RequestDispatcher之后。
I encountered this similar problem while creating a simple LoginServlet
, where I have defined Writer
after declaring RequestDispatcher
.
我在创建一个简单的LoginServlet时遇到了类似的问题,我在声明RequestDispatcher之后定义了Writer。
Try defining Writer
class object before RequestDispatcher
class.
尝试在RequestDispatcher类之前定义Writer类对象。