response.getOutputStream() 首次调用时抛出 IllegalStateException
Posted
技术标签:
【中文标题】response.getOutputStream() 首次调用时抛出 IllegalStateException【英文标题】:response.getOutputStream() throws IllegalStateException when called for the first time 【发布时间】:2013-03-26 08:39:49 【问题描述】:我正在尝试从 mysql-DB 下载 pdf(我将其作为 Blob 获取,到目前为止一切正常。但是当我尝试让 ServletOutputstream 将其发送到客户端时,程序崩溃。 AFAIK 当该方法之前被调用或 getwriter-method 被调用时抛出异常。但是我根本没有在我的代码中使用 getwriter 方法,并且没有达到程序中的其他 getOutPutStream 方法(我将它们注释掉以确保)。 (如果出于任何原因这很重要,那么整个事情都发生在 JSP 中) 这是我的代码 sn-p 和异常:
代码
Blob pdf = null;
if(request.getParameter("reportId") != null)
pdf = testszenario.getReportErgebnisPdf(Integer.parseInt(request.getParameter("reportId")), request.getParameter("erzeugung"));
byte[] buf = new byte[(int)pdf.length()];
InputStream inputStream = pdf.getBinaryStream();
inputStream.read(buf);
inputStream.close();
response.setContentType("application/pdf");
response.setHeader("Content-disposition","attachment; filename=test.pdf");
ServletOutputStream sos = response.getOutputStream();
// response.getOutputStream().write(buf);
例外
26.03.2013 09:28:29 org.apache.catalina.core.ApplicationDispatcher invoke
SCHWERWIEGEND: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException
at org.apache.jasper.runtime.ServletResponseWrapperInclude.getOutputStream(ServletResponseWrapperInclude.java:63)
at org.apache.jsp.jsp.modules.Testszenario.PostReportResultOverview_jsp._jspService(PostReportResultOverview_jsp.java:115)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:630)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:535)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:472)
at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:968)
at org.apache.jsp.jsp.McFrame_jsp._jspService(McFrame_jsp.java:284)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
【问题讨论】:
【参考方案1】:请检查您的回复是否已提交。如果您尝试对已提交的响应执行某些操作,则可能会出现IllegalStateException
。如果超出页面缓冲区大小,将提交响应。
【讨论】:
你是对的,这就是问题所在。但是由于响应已经在 JSP 的开头提交,在我什至在响应缓冲区中更改或写入任何内容之前,我该如何更改呢? 但这怎么可能呢?即使我将代码更改为最低限度:<%@page import="com.nundp.util.ResourceHandler,java.util.*,java.io.*,java.sql.Blob"%> <%System.out.println("start jsp: " + response.isCommitted());%>
响应已经提交?
好吧,我发现了错误。该 jsp 是通过另一个“框架”-jsp 调用的,其中包含导航等,因此响应已经提交。但是由于被调用的jsp不是用于显示目的(我知道那是非常糟糕的做法),因此无需通过frame-jsp调用它,并且在直接寻址时它可以工作。谢谢 NilsH。【参考方案2】:
在 JSP 中执行此操作可能确实很重要。请记住,JSP 是 Web 应用程序请求的输出渲染阶段的一部分,因此容器可能已经获取了 writer 对象。尝试将您的代码移动到 servlet 中。它可以让您更好地控制作者/流。
【讨论】:
以上是关于response.getOutputStream() 首次调用时抛出 IllegalStateException的主要内容,如果未能解决你的问题,请参考以下文章
Java Web报错:getOutputStream() has already been called for this response解决方案
response.getOutputStream();是否在servlet里面就不可以请求转发或者重定向,有啥解决方法
是否应该在 HttpServletResponse.getOutputStream()/.getWriter() 上调用 .close()?