webentwicklung-frage-antwort-db.com.de

für diese Antwort wurde bereits getOutputStream () aufgerufen

Ich google die Fehlermeldung getOutputStream() has already been called for this response Und viele Leute sagten, es sei wegen Leerzeichen oder Zeilenumbrüchen nach <% oder %>, aber in meinem Code gibt es keine Leerzeichen oder Zeilenumbrüche. Ich verwende Tomcat6 unter Linux.

<%@
    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)

ursache 

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)
53
Southsouth

Ok, Sie sollten ein servlet keine JSP verwenden, aber wenn Sie wirklich ... brauchen, fügen Sie diese Anweisung oben auf Ihrer Seite hinzu:

<%@ page trimDirectiveWhitespaces="true" %>

Oder im Abschnitt "jsp-config" Ihre web.xml

<jsp-config>
  <jsp-property-group>
    <url-pattern>*.jsp</url-pattern>
    <trim-directive-whitespaces>true</trim-directive-whitespaces>
  </jsp-property-group>
</jsp-config>

Auch flush/close die OutputStream und kehrt zurück, wenn Sie fertig sind.

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

Das Problem hierbei ist, dass Ihre JSP direkt mit der Antwort OutputStream spricht. Technisch ist dies nicht verboten, aber es ist keine gute Idee.

Insbesondere rufen Sie response.getOutputStream() auf und schreiben Daten in diese. Wenn die JSP-Engine später versucht, die Antwort zu leeren, schlägt sie fehl, weil Ihr Code die Antwort bereits "beansprucht" hat. Eine Anwendung kann entweder getOutputStream oder getWriter für eine bestimmte Antwort aufrufen. Es ist nicht zulässig, beides auszuführen. JSP-Engines verwenden getWriter, sodass Sie getOutputStream nicht aufrufen können.

Sie sollten diesen Code als Servlet und nicht als JSP schreiben. JSPs eignen sich nur für die Textausgabe, wie sie in der JSP enthalten ist. Sie sehen, dass in Ihrer JSP keine eigentliche Textausgabe vorliegt, diese enthält nur Java. 

35
skaffman

Fügen Sie Folgendes am Ende von try/catch hinzu, um den Fehler zu vermeiden, der auftritt, wenn die JSP-Engine die Antwort über getWriter () löscht.

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

Wie bereits erwähnt, ist dies keine bewährte Methode, es vermeidet jedoch die Fehler in Ihren Protokollen.

9
pnairn

Dieses Problem hatte ich erst beim zweiten Mal zum Exportieren. Sobald ich hinzugefügt habe:

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

nachdem der Export abgeschlossen war, funktionierte mein Code die ganze Zeit. 

4
michaelp

Ich habe gerade dieses Problem erfahren. 

Das Problem wurde dadurch verursacht, dass meine Controller-Methode beim Beenden den Rückgabetyp von String (Name der Ansicht) versucht. Wenn die Methode beendet wird, wird ein zweiter Antwortstrom initiiert. 

Das Ändern des Rückgabetyps der Controller-Methode in void hat das Problem behoben.

Ich hoffe, das hilft, wenn jemand anderes dieses Problem erfährt.

3
Dan Torrey

Hier ist, was in einem ähnlichen Fall für mich funktioniert hat.

Wenn Sie mit dem Schreiben in die ServletOutputStream fertig sind, rufen Sie einfach response.sendRedirect("yourPage.jsp"); auf. Dies würde dazu führen, dass eine neue Anforderung vom Browser aus initiiert wird. Vermeiden Sie daher das Schreiben in denselben Ausgabestrom.

3
Igor

JSP ist das Präsentations-Framework von JSP und sollte im Allgemeinen keine Programmlogik enthalten. Verwenden Sie, wie von skaffman vorgeschlagen, reine Servlets oder ein beliebiges MVC-Web-Framework, um das zu erreichen, was Sie möchten.

2
Bozho

Ich habe die gleiche Fehlermeldung erhalten, wenn ich response.getWriter() vor einer request.getRequestDispatcher(path).forward(request, response); verwende. Der Start funktioniert also gut, wenn ich ihn durch response.getOutputStream() ersetze.

0
Daniel De León

Ich habe das gleiche Problem, und ich habe nur das Hinzufügen von "return" gelöst; am Ende des FileInputStream.

Hier ist meine 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>
0

Dieser Fehler ist in meinem Programm aufgetreten, weil das Resultset mehr Spalten aufgerufen hat, die im Dokument PDF angezeigt werden sollen, als in der Datenbank enthalten waren. Die Tabelle enthält beispielsweise 30 Felder, aber das Programm hat 35 aufgerufen (resultset.getString (35)).

0
Wandile Nxumalo