it-swarm.com.ru

getOutputStream () уже был вызван для этого ответа

Я гуглю сообщение об ошибке getOutputStream() has already been called for this response И многие люди говорят, что это из-за пробела или новой строки после <% или %>, но в моем коде нет пробела или новой строки. Я использую Tomcat6 на 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)

первопричина 

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

Хорошо, вы должны использовать сервлет не JSP, но если вам действительно нужно ... добавить эту директиву вверху вашей страницы:

<%@ 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;
48
RealHowTo

Проблема в том, что ваш JSP напрямую обращается к ответу OutputStream. Технически это не запрещено, но это не очень хорошая идея.

В частности, вы вызываете response.getOutputStream() и записываете данные для этого. Позже, когда механизм JSP пытается очистить ответ, он завершается неудачно, потому что ваш код уже «запросил» ответ. Прикладная программа может вызывать getOutputStream или getWriter для любого данного ответа, и не разрешено делать оба. Механизмы JSP используют getWriter, поэтому вы не можете вызывать getOutputStream.

Вы должны писать этот код в виде сервлета, а не JSP. JSP действительно подходят только для текстового вывода, содержащегося в JSP. Вы можете видеть, что в вашем JSP нет текстового вывода, он содержит только Java. 

35
skaffman

Добавьте следующее в конец try/catch, чтобы избежать ошибки, которая появляется, когда механизм JSP сбрасывает ответ через getWriter ()

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

Как уже было отмечено, это не лучшая практика, но она позволяет избежать ошибок в ваших журналах.

9
pnairn

У меня была эта проблема только во второй раз, когда я пошел на экспорт. Однажды я добавил:

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

после завершения экспорта мой код начал работать все время. 

4
michaelp

Я только что испытал эту проблему. 

Проблема была вызвана тем, что мой метод контроллера пытался вернуть тип String (имя представления) при выходе. Когда метод завершится, будет инициирован второй поток ответа. 

Изменение типа возврата метода контроллера на void решило проблему.

Я надеюсь, что это поможет, если кто-то еще испытывает эту проблему.

3
Dan Torrey

Вот что у меня сработало в аналогичном случае.

После того, как вы закончите запись в ServletOutputStream, просто вызовите response.sendRedirect("yourPage.jsp");. Это может привести к инициированию нового запроса от браузера, поэтому избегайте записи в тот же поток вывода.

3
Igor

JSP - это структура представления, и, как правило, не должна содержать в ней никакой программной логики. Как предложил Скаффман, используйте чистые сервлеты или любую веб-инфраструктуру MVC, чтобы добиться того, чего вы хотите.

2
Bozho

Я получил ту же ошибку, используя response.getWriter() перед request.getRequestDispatcher(path).forward(request, response);. Так что начало отлично работает, когда я заменяю его на response.getOutputStream()

0
Daniel De León

У меня возникла та же проблема, и я решил просто добавить «возврат»; в конце 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>
0
diego matos - keke

Эта ошибка произошла в моей программе, потому что набор результатов вызывал больше столбцов для отображения в документе PDF, чем содержала база данных. Например, таблица содержит 30 полей, но программа вызывала 35 (resultset.getString (35))

0
Wandile Nxumalo