java 非法状态异常:已经为此响应调用了 getwriter()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11721330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Illegalstateexception: getwriter() has already been called for this response
提问by Krishnanunni P V
I am trying to open pdf file in browser using the following code snippet:
我正在尝试使用以下代码片段在浏览器中打开 pdf 文件:
public ActionResult action(Request request, AspectModel arg1)
throws ServletException {
if ("PDF".equals(request.event())) {
try{
HttpServletResponse resp=(HttpServletResponse) request.getResponse();
resp.setContentType("application/pdf");
resp.setHeader("Content-Disposition","inline;filename=AccountOpeningSummary.pdf");
resp.setHeader("Cache-Control", "cache, must-revalidate");
resp.setHeader("Cache-Control", "no-store,public");
resp.setDateHeader("Expires", 0);
resp.setHeader("Pragma", "public");
OutputStream OutStream = resp.getOutputStream();
OutStream.write(infos,0,infos.length);
OutStream.flush();
OutStream.close();
}catch (Exception e) {
System.out.println("PDF Write Exception...........................####"+e);
}
}
return null;
}
I am getting the following error:
我收到以下错误:
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:626)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:215)
at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:105)
at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
at org.apache.jasper.runtime.JspWriterImpl.flush(JspWriterImpl.java:177)
at abaxx.web.taglib.IncludeTag.doEndTag(IncludeTag.java:69)
at org.apache.jsp.parts.index_jsp._jspx_meth_xx_005finclude_005f0(index_jsp.java:237)
at org.apache.jsp.parts.index_jsp._jspService(index_jsp.java:93)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:419)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:389)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:333)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:593)
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:530)
at abaxx.core.foundation.internal.SelfDestroyingHttpServletRequestWrapper.include(SelfDestroyingHttpServletRequestWrapper.java:36)
at abaxx.core.foundation.internal.SelfDestroyingHttpServletRequestWrapper.include(SelfDestroyingHttpServletRequestWrapper.java:36)
at abaxx.web.parts.internal.ServletRequestContext.doInclude(ServletRequestContext.java:85)
at abaxx.web.parts.RequestContext.include(RequestContext.java:429)
at abaxx.web.parts.VisualPart.basicDisplay(VisualPart.java:740)
at abaxx.web.parts.CompositePart.basicDisplay(CompositePart.java:111)
at abaxx.web.parts.VisualPart.doDisplay(VisualPart.java:762)
at abaxx.web.control.DisplayLoopInterceptor.display(DisplayLoopInterceptor.java:233)
at abaxx.web.security.StandardSecurityPolicy$DisplayHook.display(StandardSecurityPolicy.java:321)
at abaxx.web.control.PerformanceMonitor$DisplayPerformanceInterceptor.display(PerformanceMonitor.java:187)
at abaxx.web.control.DisplayLoopInterceptor.doDisplay(DisplayLoopInterceptor.java:80)
at abaxx.web.parts.VisualPart.display(VisualPart.java:104)
at abaxx.web.control.DisplayLoopInterceptor.process(DisplayLoopInterceptor.java:128)
at vanilla.portal.builder.PBDisplayLoopInterceptor.process(PBDisplayLoopInterceptor.java:60)
at vanilla.common.EncodingExtension$ResponseEncodingInterceptor.process(EncodingExtension.java:107)
at abaxx.web.preferences.PreferencesHookup.process(PreferencesHookup.java:126)
at vanilla.common.HttpHeaderInterceptor.process(HttpHeaderInterceptor.java:36)
at abaxx.web.control.PageflowInterceptor.process(PageflowInterceptor.java:62)
at abaxx.workflow.pageflow.PageflowInterceptor.process(PageflowInterceptor.java:93)
at abaxx.web.control.ActionInterceptor.process(ActionInterceptor.java:49)
at abaxx.web.security.StandardSecurityPolicy$ActionHook.process(StandardSecurityPolicy.java:211)
at abaxx.web.control.SessionTimeoutInterceptor.process(SessionTimeoutInterceptor.java:59)
at abaxx.track.TrackingInterceptor.finishTracking(TrackingInterceptor.java:151)
at abaxx.track.TrackingInterceptor.process(TrackingInterceptor.java:100)
at abaxx.web.control.AccessViolationInterceptor.process(AccessViolationInterceptor.java:110)
at abaxx.web.control.RequestProcessor$P9.process(RequestProcessor.java:72)
at abaxx.web.control.PerformanceMonitor$RequestPerformanceInterceptor.process(PerformanceMonitor.java:153)
at vanilla.common.EncodingExtension$RequestEncodingInterceptor.process(EncodingExtension.java:61)
at abaxx.web.control.MaintenanceInterceptor.process(MaintenanceInterceptor.java:44)
at abaxx.web.control.AbaXXComponentsHookup$ClientSessionHookupInterceptor.process(AbaXXComponentsHookup.java:42)
at abaxx.web.security.SecurityPolicy$FakeContainerLoginInterceptor.process(SecurityPolicy.java:136)
at abaxx.web.control.RequestProcessor.process(RequestProcessor.java:187)
at abaxx.web.control.ApplicationServlet.doGet(ApplicationServlet.java:144)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at abaxx.web.control.url.RequestFilter.doFilter(RequestFilter.java:28)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at abaxx.web.control.CachingHeaderFilter.doFilter(CachingHeaderFilter.java:29)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at vanilla.common.EncodingExtension.doFilter(EncodingExtension.java:121)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:403)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:301)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:162)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
I have also tried by closing the getWriter()
using:
我也尝试过关闭getWriter()
使用:
HttpServletResponse resp=(HttpServletResponse) request.getResponse();
Writer rt=resp.getWriter();
resp.getWriter().close();
Can anyone help me?
谁能帮我?
采纳答案by Harald Gliebe
Which version of abaxx are you using? In recent versions you can return ActionResult.ABORT from the action method if you genereate the response in the controller. If you return null the framework will proceed to the display-phase and render the JSP.
您使用的是哪个版本的 abaxx?在最近的版本中,如果您在控制器中生成响应,您可以从操作方法返回 ActionResult.ABORT。如果您返回 null,框架将进入显示阶段并呈现 JSP。
回答by Jon Skeet
EDIT: Now that the question has changed significantly...
编辑:现在问题发生了重大变化......
It sounds like the JSP is still trying to render itself as the response. You need to tell the container that you're handling the request - ideally you shouldn't go anywhere near a JSP, as this is presumably a request justfor the PDF. You should configure the container to call a separate servlet to download the PDF; that way you won't get the JSP part involved at all.
听起来 JSP 仍在尝试将自己呈现为响应。您需要告诉容器您正在处理请求 - 理想情况下,您不应靠近 JSP,因为这可能只是针对 PDF的请求。您应该将容器配置为调用单独的 servlet 来下载 PDF;这样你就不会涉及到 JSP 部分。
(And yes, that will mean moving the code you've shown in the question. That's presumably currently part of a JSP; it shouldn't be.)
(是的,这意味着移动您在问题中显示的代码。这大概是当前 JSP 的一部分;它不应该是。)
回答by BalusC
That's because you've put that PDF generating code which uses the response output stream in a JSP file by <jsp:include>
. JSP files implicitly use the response writer because JSP files are designed to generate HTML code which is character based (and not binary based like PDF files). JSP is in first place the wrong place to put PDF generating code in. HTML and PDF don't mix very well.
那是因为您已将使用响应输出流的 PDF 生成代码放入 JSP 文件中<jsp:include>
。JSP 文件隐式地使用响应编写器,因为 JSP 文件旨在生成基于字符(而不是像 PDF 文件那样基于二进制)的 HTML 代码。JSP 首先是放置 PDF 生成代码的错误位置。HTML 和 PDF 不能很好地混合。
To solve your design problem, you need to create a simple class extending HttpServlet
, move all that Java code into the doGet()
method (or doPost()
, depending on what kind of requests you'd like to respond on). Finally map that servlet on a desired URL pattern by @WebServlet
annotation or <servlet-mapping>
in web.xml
and change the URL of the PDF request from the JSP one to the servlet one.
为了解决您的设计问题,您需要创建一个简单的扩展类HttpServlet
,将所有 Java 代码移动到该doGet()
方法中(或者doPost()
,取决于您想要响应的请求类型)。最后通过@WebServlet
注释或<servlet-mapping>
in将该 servlet 映射到所需的 URL 模式web.xml
,并将 PDF 请求的 URL 从 JSP 更改为 servlet 1。
Here's a basic kickoff example assuming that you're using a Servlet 3.0 compatible container such as Tomcat 7, Glassfish 3, etc so that you can use @WebServlet
annotation:
这是一个基本的启动示例,假设您使用的是 Servlet 3.0 兼容容器,例如 Tomcat 7、Glassfish 3 等,以便您可以使用@WebServlet
注释:
@WebServlet("/pdfServlet")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Put your code here.
}
}
Invoke it by http://localhost:8080/contextname/pdfServlet
instead of index.jsp
.
通过http://localhost:8080/contextname/pdfServlet
代替调用它index.jsp
。
If your requirement is after all to present the PDF inline in a HTML page, then you need <iframe>
instead of <jsp:include>
. E.g.
如果您的要求毕竟是在 HTML 页面中内联显示 PDF,那么您需要<iframe>
而不是<jsp:include>
. 例如
<iframe src="pdfServlet"></iframe>
This way the browser will download the PDF file by an entirely separate HTTP request.
这样浏览器将通过一个完全独立的 HTTP 请求下载 PDF 文件。