【问题标题】:User cancelled file download in Grails用户在 Grails 中取消了文件下载
【发布时间】:2013-08-01 04:57:08
【问题描述】:

如何正确处理取消的文件下载?有问题的文件是一个相当大的 zip 文件,需要很长时间才能构建,因此用户有足够的时间点击下载对话框窗口上的“取消”按钮。

当它发生时,会发生一个令人讨厌的异常(见下文),这是意料之中的,因为客户端破坏了管道。但是怎么清理呢?在哪里/什么是捕获异常的正确方法,以便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

【问题讨论】:

    标签: grails


    【解决方案1】:

    这似乎工作得很好:

    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"
      }
    }
    

    【讨论】:

    • 所以我不必在我的路径中包含 tomcat 我捕获了 IOException
    【解决方案2】:

    我可以看到:

    原因: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)
    

    这应该会有所帮助。

    【讨论】:

      猜你喜欢
      • 2013-06-26
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      • 2020-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多