Подтвердить что ты не робот

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

Я google сообщение об ошибке 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)
4b9b3361

Ответ 1

Хорошо, вы должны использовать сервлет не 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;

Ответ 2

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

Ответ 5

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

После завершения записи в Servlet OutputStream просто позвоните response.sendRedirect("yourPage.jsp");. Это вызовет инициирование нового запроса в браузере, поэтому не записывайте его в один выходной поток.

Ответ 6

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

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

Изменение типа возвращаемого метода контроллера на void устраняет проблему.

Надеюсь, это поможет, если кто-нибудь еще столкнется с этой проблемой.

Ответ 7

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

Ответ 8

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

Ответ 9

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

Ответ 10

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

Ответ 11

Вместо этого используйте Glassfish 4.0. Это оказывается проблемой только в выпуске Glassfish 4.1.1.

PT-BR: Используйте o Glasfish 4.0. Este parece ser um problema apenas no Glassfish 4.1.1.

Ответ 12

В некоторых случаях этот случай возникает, когда вы объявляете

Writer out=response.getWriter   

после объявления или использования RequestDispatcher.

Я столкнулся с подобной проблемой при создании простой LoginServlet, где я определил Writer после объявления RequestDispatcher.

Попробуйте определить объект класса Writer до класса RequestDispatcher.