2012-06-01 24 views
6

我有一個名爲GetFile的操作,它直接打開文件下載框來打開PDF。struts2 - java.lang.IllegalStateException在動作調用結果流時發生間歇性下載PDF文件

下面是struts.xml的配置和相同的動作類。我使用結果類型作爲流來實現這一點。我可以看到PDF下載框始終打開,我也可以下載文件。

但我發現昨天晚上有一些請求已經觸發了該操作,並且它產生了下面的錯誤。

org.apache.jasper.JasperException: java.lang.IllegalStateException: getOutputStream() has already been called for this response 
     at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:570) 
     at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:452) 
     at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:391) 
     at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334) 
     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 org.apache.struts2.dispatcher.ServletDispatcherResult.doExecute(ServletDispatcherResult.java:159) 
     at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186) 
     at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:374) 
     at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:278) 
     at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:211) 
     at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) 
     at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
     at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:187) 
     at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
     at deshaw.irweb.web.interceptor.AuthInterceptor.intercept(AuthInterceptor.java:60) 
     at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:249) 
     at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54) 
     at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:510) 
     at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:434) 
     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:498) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) 
     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394) 
     at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:294) 
     at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:183) 
     at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:169) 
     at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
     at java.lang.Thread.run(Thread.java:722) 
Caused by: java.lang.IllegalStateException: getOutputStream() has already been called for this response 
     at org.apache.catalina.connector.Response.getWriter(Response.java:636) 
     at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:205) 
     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.PageContextImpl.release(PageContextImpl.java:182) 
     at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:123) 
     at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:80) 
     at org.apache.jsp.jsp.ServerError_jsp._jspService(ServerError_jsp.java:157) 
     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) 
     ... 38 more  

有人能告訴我什麼可能導致了這個問題?目前我無法再現問題。我在某處讀到這可能是由於關閉了下載對話框,但即使在我嘗試使用多個瀏覽器後,情況並非如此。還檢查了getOutputStream() has already been called for this response,但不能直接與我的問題相關聯,因爲沒有重定向到jsp,因爲struts2操作直接導致結果流。

struts.xml中
<action name="GetFile" class="Class" method="DownloadFile"> 
      <result name="success" type="stream"> 
      <param name="contentType">contentType</param> 
      <param name="contentDisposition">fileName</param> 
      <param name="bufferSize">1024</param> 
      <param name="inputName">inputStream</param> 
      </result> 
</action> 

Action類

public String DownloadFile() 
{ 
     // create the object variable pdfdoc which is a custom object. 
     // You can assume that the pdfdoc is properly constructed 
     // and getFileContent does what it is required to do, so 
     // that the final pdf is generated. 
     ... 
     ... 
     inputStream = new ByteArrayInputStream(pdfdoc.getFileContent()); 
     contentType = pdfdoc.getContentType(); 
     fileName = pdfdoc.getFileName(); 
     contentDisposition = doc.getContentDisposition(); 
     bufferSize = 1024; 
     return "success"; 

} 
+0

能否請您發佈完整的堆棧跟蹤,並在很短,如果這種行爲是不可再生的硬猜測用戶的行爲。 –

+0

已添加完整堆棧跟蹤 –

+0

該操作是否採用任何參數? –

回答

1

我使用Internet Explorer時也有類似的問題,並通過在響應報頭添加此固定它:

response.setHeader("Expires","0"); 
response.setHeader("Pragma","cache"); 
response.setHeader("Cache-Control","private"); 

也許您在日誌中看到的由Internet Explorer生成的請求。

看一看herehere

更新:要打印在日誌的瀏覽器版本,你可以做這樣的事情:

System.out.println(request.getHeader("User-Agent")); 
+0

謝謝。雖然它可能是IE的一個問題,你能告訴我在IE中確切的用戶行爲,可能會幫助我重現問題嗎? –

+0

嘗試使用多個版本的IE,並且在測試時從受信任的站點中刪除您的URL並查看日誌,以查看當提示您的下載被阻止時發生的情況。 – tibtof

+1

@TGV如果我的回答沒有任何幫助,請告訴我,我會將其刪除。我不想得到不應得的賞金。 – tibtof