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引擎尝试刷新响应时,它会失败,因为您的代码已经“声明”响应。 应用程序可以在任何给定的响应中调用getOutputStream
或getWriter
,但不能同时执行这两个操作。 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。