2013-05-01 67 views
2

如何正確處理取消的文件下載?有問題的文件是一個非常大的zip文件,需要很長時間才能生成,因此用戶有足夠的時間在他的下載對話框窗口中點擊取消按鈕。用戶在Grails中取消文件下載

發生這種情況時,會發生一個令人討厭的異常(請參見下文),這是預料之中的,因爲客戶端破壞了管道。但如何清理它?在哪裏/什麼是正確的方法來捕捉異常,以便tomcat日誌不會被他們丟棄?

謝謝。

下載代碼本身是從教科書非常標準的代碼:

import java.util.zip.ZipEntry 
import java.util.zip.ZipOutputStream 

def getZipFile(params) { 
    response.setHeader("Expires", "0"); 
    response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); 
    response.setHeader("Pragma", "public"); 
    response.setHeader("Content-Disposition", "attachment; filename=\"filename.zip\""); 
    response.contentType = "application/zip" 

    def zos = new ZipOutputStream(response.outputStream) 
    zos = functionThatCreatesTheZipFile(zos, params) // this takes some time 
    zos.close() 
} 

例外:

rfpmgr [2013-05-01 10:14:32.337] ERROR: web.errors.GrailsExceptionResolver IOException occurred when processing request: [GET] /rfpManager/report/downloadZipFile 
Stacktrace follows: 
java.io.IOException 
at java.util.zip.ZipOutputStream.writeBytes(ZipOutputStream.java:617) 
at java.util.zip.ZipOutputStream.writeCEN(ZipOutputStream.java:501) 
at java.util.zip.ZipOutputStream.finish(ZipOutputStream.java:348) 
at java.util.zip.DeflaterOutputStream.close(DeflaterOutputStream.java:238) 
at java.util.zip.ZipOutputStream.close(ZipOutputStream.java:360) 
at gov.usgs.eventManager.ZipService.getZipFile(ZipService.groovy:32) 
at gov.usgs.eventManager.ReportController$_closure18.doCall(ReportController.groovy:738) 
at gov.usgs.jdt.josso.spring.JOSSOProcessingFilter.doFilter(JOSSOProcessingFilter.java:144) 
at gov.usgs.jdt.josso.agent.GenericServletSSOAgentFilter.doFilter(GenericServletSSOAgentFilter.java:431) 
at java.lang.Thread.run(Thread.java:722) 
rfpmgr [2013-05-01 10:14:32.354] ERROR: web.errors.GrailsExceptionResolver IllegalStateException occurred when processing request: [GET] /rfpManager/report/downloadZipFile 
getOutputStream() has already been called for this response. Stacktrace follows: 
org.codehaus.groovy.grails.web.pages.exceptions.GroovyPagesException: Error processing GroovyPageView: getOutputStream() has already been called for this response 
at gov.usgs.jdt.josso.spring.JOSSOProcessingFilter.doFilter(JOSSOProcessingFilter.java:144) 
at gov.usgs.jdt.josso.agent.GenericServletSSOAgentFilter.doFilter(GenericServletSSOAgentFilter.java:431) 
at java.lang.Thread.run(Thread.java:722) 
Caused by: java.lang.IllegalStateException: getOutputStream() has already been called for this response 
at gsp_rfpManager_errorserrors_gsp.run(gsp_rfpManager_errorserrors_gsp.groovy:17) 
... 3 more 

回答

2

這似乎就好了工作:

import java.util.zip.ZipEntry 
import java.util.zip.ZipOutputStream 
import org.apache.catalina.connector.ClientAbortException 

def getZipFile(params) { 
    response.setHeader("Expires", "0"); 
    response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0"); 
    response.setHeader("Pragma", "public"); 
    response.setHeader("Content-Disposition", "attachment; filename=\"filename.zip\""); 
    response.contentType = "application/zip" 

    try { 
    def zos = new ZipOutputStream(response.outputStream) 
    zos = functionThatCreatesTheZipFile(zos, params) // this takes some time 
    zos.close() 
    } 
    catch (ClientAbortException ex) { 
    println "user aborted download" 
    } 
} 
+0

所以我不必在我的路徑中包含tomcat我抓到了IOException – 2015-05-12 03:11:44

0

我可以看到有:

產生的原因:java.lang.IllegalStateException:getOutputStream方法()已經被調用,這種響應

這是Grails的控制器共同當直接渲染的東西。解決方案:

render (file: <InputStream>, contentType: 'image/jpeg') 
//or 
render (file: <byte[]>, contentType: 'image/jpeg') 
//or 
GrailsWebRequest webRequest = 
      (GrailsWebRequest) RequestContextHolder.currentRequestAttributes() 
webRequest.setRenderView(false) 

這應該有所幫助。