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)
11 ответов:
хорошо, вы должны использовать сервлет не JSP но если вам действительно нужно... добавить эту директиву в верхней части страницы:
<%@ page trimDirectiveWhitespaces="true" %>
или в разделе JSP-config ваш веб.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
theOutputStream
и вернуться, когда закончите.dataOutput.flush(); dataOutput.close(); return;
проблема здесь в том, что ваш JSP разговаривает непосредственно с ответом
OutputStream
. Технически это не запрещено, но это очень плохая идея.в частности, вы называете
response.getOutputStream()
и записать данные на это. Позже, когда механизм JSP пытается сбросить ответ, он терпит неудачу, потому что ваш код уже "заявил" ответ. Приложение может либо вызватьgetOutputStream
илиgetWriter
на любой данный ответ, это не разрешается делать оба. Двигатели JSP используютgetWriter
, и поэтому вы не можете звонитеgetOutputStream
.вы должны писать этот код как сервлет, а не JSP. Jsp действительно подходят только для текстового вывода, содержащегося в JSP. Вы можете видеть, что в вашем JSP нет фактического вывода текста, он содержит только java.
добавьте следующее В конце try / catch, чтобы избежать ошибки, которая появляется, когда двигатель JSP сбрасывает ответ через getWriter ()
out.clear(); // where out is a JspWriter out = pageContext.pushBody();
Как уже было отмечено, это не лучшая практика, но она позволяет избежать ошибок в логах.
Я только что испытал эту проблему.
проблема была вызвана моим методом контроллера, пытающимся вернуть тип строка (имя представления) когда она выходит. Когда метод выйдет, будет инициирован второй поток ответа.
изменение типа возврата метода контроллера на пустота проблема решена.
Я надеюсь, что это поможет, если кто-то еще испытывает эту проблему.
У меня была эта проблема только во второй раз, когда я пошел на экспорт. Однажды я добавил:
response.getOutputStream().flush(); response.getOutputStream().close();
после завершения экспорта мой код начал работать все время.
вот что сработало для меня в подобном случае.
после того, как вы закончите писать в
Servlet
OutputStream
просто позвониresponse.sendRedirect("yourPage.jsp");
. Это приведет к инициализации нового запроса из браузера, поэтому избегайте записи в тот же выходной поток.
JSP-это структура представления s и, как правило, не должна содержать в себе никакой программной логики. Как skaffman предложил, использовать чистые сервлеты, или любой веб-фреймворк с MVC для того, чтобы достичь того, чего вы хотите.
эта ошибка возникла в моей программе, потому что результирующий набор вызывал больше столбцов для отображения в PDF-документе, чем в базе данных. Например, таблица содержит 30 полей, но программа вызывала 35 (resultset.getString (35))
я получил ту же ошибку, используя
response.getWriter()
доrequest.getRequestDispatcher(path).forward(request, response);
. Так что начните работать нормально, когда я заменяю его наresponse.getOutputStream()
вместо того, чтобы использовать сервер GlassFish 4.0. Это, оказывается, проблема только в версии GlassFish в 4.1.1.
PT-BR: Используйте o Glasfish 4.0. Este parece ser um problema apenas no Glassfish 4.1.1.
в некоторых случаях это происходит при объявлении
Writer out=response.getWriter
после объявления или используя
RequestDispatcher
.я столкнулся с этой подобной проблемой при создании простого
LoginServlet
, где определеноWriter
после объявленияRequestDispatcher
.попробовать определением
Writer
объект класса передRequestDispatcher
класса.