已经为此响应调用了getOutputStream()

Sou*_*uth 56 java jsp tomcat

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

%>
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

根本原因

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)
Run Code Online (Sandbox Code Playgroud)

Rea*_*wTo 50

好吧,您应该使用servlet而不是JSP,但如果您确实需要...在页面顶部添加此指令:

<%@ page trimDirectiveWhitespaces="true" %>
Run Code Online (Sandbox Code Playgroud)

或者在你的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>
Run Code Online (Sandbox Code Playgroud)

此外flush/ closeOutputStream和完成后返回.

dataOutput.flush();
dataOutput.close();
return;
Run Code Online (Sandbox Code Playgroud)

  • 你确认这有效吗?我怀疑它会有什么不同,容器仍然会调用`getWriter`,无论页面内容如何. (3认同)
  • 这并没有为我修复错误,但确实修复了我过多的空白区域. (2认同)

ska*_*man 35

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

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

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

  • 嗯,你不能,不喜欢这样.JSP用于文本,而不是二进制. (4认同)
  • +1.原始java代码属于java类.仅在JSP中使用taglibs/EL.如果taglibs/EL不可能,请使用servlet. (4认同)
  • northTiger,即使项目是所有JSP,也没有什么能阻止你添加Servlet.一旦编译完成,JSP就会成为servlet.对于使用PDF,使用普通的servlet可以获得更好的效果. (3认同)
  • 是的,我同意你们使用servlet.但是servket需要更多配置. (3认同)

pna*_*irn 9

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

out.clear(); // where out is a JspWriter
out = pageContext.pushBody();
Run Code Online (Sandbox Code Playgroud)

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


mic*_*elp 5

我只有第二次去出口时才遇到这个问题。一旦添加:

response.getOutputStream().flush();
response.getOutputStream().close();
Run Code Online (Sandbox Code Playgroud)

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