getOutputStream()已经被调用了这个响应

我谷歌的错误信息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) 

好的,你应该使用一个不是JSP的servlet,但是如果你真的需要……在页面顶部添加这个指令:

 <%@ page trimDirectiveWhitespaces="true" %> 

或者在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> 

同时flush / close OutputStream ,完成后返回。

 dataOutput.flush(); dataOutput.close(); return; 

这里的问题是你的JSP直接与OutputStream响应通话。 这在技术上不是禁止的,但是这不是一个好主意。

具体来说,你可以调用response.getOutputStream()并写入数据。 之后,当JSP引擎尝试刷新响应时,它会失败,因为您的代码已经“声明”响应。 应用程序可以在任何给定的响应中调用getOutputStreamgetWriter ,但不能同时执行这两个操作。 JSP引擎使用getWriter ,所以你不能调用getOutputStream

您应该将此代码编写为Servlet,而不是JSP。 JSP仅适用于JSP中包含的文本输出。 你可以看到在JSP中没有实际的文本输出,它只包含java。

在try / catch结尾添加以下内容以避免JSP引擎通过getWriter()刷新响应时出现的错误

 out.clear(); // where out is a JspWriter out = pageContext.pushBody(); 

如前所述,这不是最好的做法,但它可以避免日志中的错误。

我刚遇到这个问题。

这个问题是由我的控制器方法在退出时试图返回Stringtypes(视图名称)造成的 。 当该方法退出时,将启动第二个响应stream。

更改控制器方法返回types为void解决了问题。

我希望这有助于其他人遇到这个问题。

我只有第二次出口这个问题。 一旦我补充说:

 response.getOutputStream().flush(); response.getOutputStream().close(); 

导出完成后,我的代码一直在工作。

在类似的情况下,这是我的工作。

完成写入Servlet OutputStream只需调用response.sendRedirect("yourPage.jsp"); 。 这将导致从浏览器发起新的请求,因此避免写入相同的输出stream。

JSP是表示框架,通常不应该包含任何程序逻辑。 正如skaffman所build议的,使用纯servlet或者任何MVC web框架来实现你想要的。

在我的程序中发生了这个错误,因为结果集调用了更多的列在PDF文档中显示而不是包含的数据库。 例如,该表包含30个字段,但程序调用35(resultset.getString(35))

通过在request.getRequestDispatcher(path).forward(request, response);之前使用response.getWriter() ,我得到了同样的错误request.getRequestDispatcher(path).forward(request, response); 。 所以开始工作正常时,我把它replaceresponse.getOutputStream()

改用Glassfish 4.0。 这只是Glassfish 4.1.1发行版中的一个问题。

PT-BR:使用Glasfish 4.0。 Este parece ser um problema apenas no Glassfish 4.1.1。