我谷歌错误消息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)
根本原因
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)
答案 0 :(得分:49)
好的,您应该使用 servlet 而非JSP,但如果您确实需要...在页面顶部添加此指令:
<%@ page trimDirectiveWhitespaces="true" %>
或者在你的web.xml的jsp-config部分
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<trim-directive-whitespaces>true</trim-directive-whitespaces>
</jsp-property-group>
</jsp-config>
同样flush
/ close
OutputStream
并在完成后返回。
dataOutput.flush();
dataOutput.close();
return;
答案 1 :(得分:35)
这里的问题是您的JSP直接与响应OutputStream
对话。这在技术上是不被禁止的,但这不是一个好主意。
具体来说,您调用response.getOutputStream()
并向其写入数据。稍后,当JSP引擎尝试刷新响应时,它会失败,因为您的代码已经“声明”了响应。应用程序可以在任何给定的响应上调用getOutputStream
或getWriter
,但不允许同时执行这两项操作。 JSP引擎使用getWriter
,因此您无法调用getOutputStream
。
您应该将此代码编写为Servlet,而不是JSP。 JSP仅适用于JSP中包含的文本输出。您可以看到JSP中没有实际的文本输出,它只包含java。
答案 2 :(得分:9)
在try / catch的末尾添加以下内容,以避免JSP引擎通过getWriter()
刷新响应时出现的错误out.clear(); // where out is a JspWriter
out = pageContext.pushBody();
正如已经指出的那样,这不是最佳做法,但它可以避免日志中的错误。
答案 3 :(得分:4)
我第二次出口时才遇到这个问题。一旦我加入:
response.getOutputStream().flush();
response.getOutputStream().close();
导出完成后,我的代码一直开始工作。
答案 4 :(得分:3)
在类似的情况下,这对我有用。
写完Servlet
OutputStream
后,只需致电response.sendRedirect("yourPage.jsp");
。这将导致从浏览器启动新请求,因此避免写入相同的输出流。
答案 5 :(得分:3)
我刚遇到这个问题。
问题是由我的控制器方法在退出时尝试返回类型字符串(视图名称)引起的。当该方法退出时,将启动第二个响应流。
将控制器方法返回类型更改为 void 解决了问题。
我希望如果其他人遇到这个问题,这会有所帮助。
答案 6 :(得分:2)
JSP是表示框架,通常不应包含任何程序逻辑。正如skaffman建议的那样,使用纯servlet或任何MVC Web框架来实现您想要的目标。
答案 7 :(得分:0)
我的程序中出现此错误,因为结果集在PDF文档中调用的列数多于包含的数据库。例如,该表包含30个字段,但程序调用35(resultset.getString(35))
答案 8 :(得分:0)
我在response.getWriter()
之前使用request.getRequestDispatcher(path).forward(request, response);
时遇到了同样的错误。因此,当我用response.getOutputStream()
答案 9 :(得分:0)
我遇到了同样的问题,仅添加“ return”就解决了。在FileInputStream的末尾。
这是我的JSP
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ page import="java.io.*"%>
<%@ page trimDirectiveWhitespaces="true"%>
<%
try {
FileInputStream ficheroInput = new FileInputStream("C:\\export_x_web.pdf");
int tamanoInput = ficheroInput.available();
byte[] datosPDF = new byte[tamanoInput];
ficheroInput.read(datosPDF, 0, tamanoInput);
response.setHeader("Content-disposition", "inline; filename=export_sise_web.pdf");
response.setContentType("application/pdf");
response.setContentLength(tamanoInput);
response.getOutputStream().write(datosPDF);
response.getOutputStream().flush();
response.getOutputStream().close();
ficheroInput.close();
return;
} catch (Exception e) {
}
%>
</body>
</html>
答案 10 :(得分:0)
我没有使用JSP,但是当我通过调用PrintWriter的flush()方法或return语句将响应设置为返回JSON对象时遇到了类似的错误。先前的答案,即将return语句包装到try块中,工作方式类似于:错误消失了,因为return statement使方法忽略了try-catch下面的所有代码,特别是在我的情况下,行redirectStrategy.sendRedirect(request,response,destination_addr_string)这似乎修改了导致错误的已提交响应。就我而言,最简单的解决方案是删除行,让客户端应用程序负责重定向。
答案 11 :(得分:0)
我遇到了同样的问题,出现这个问题是因为如果您使用 getWriter()/getOutputStream() 使用多个写入器/输出流,Java 会出现错误。
对我来说,问题是我使用了 @Logging 和 @RestLogging,避免在调用 API 时使用额外的注释。
答案 12 :(得分:-1)
请改用Glassfish 4.0。这只是Glassfish 4.1.1版本中的一个问题。
PT-BR: 使用o Glasfish 4.0。 Este parece ser um problema apenas no Glassfish 4.1.1。
答案 13 :(得分:-1)
在某些情况下,当您声明
时会发生这种情况Writer out=response.getWriter
声明或使用RequestDispatcher
后。
我在创建一个简单的LoginServlet
时遇到了类似的问题,我在声明Writer
后定义了RequestDispatcher
。
尝试在Writer
类之前定义RequestDispatcher
类对象。