【问题标题】:Error processing GroovyPageView: getOutputStream() has already been called for this response处理 GroovyPageView 时出错:getOutputStream() 已为此响应调用
【发布时间】:2013-08-06 19:46:56
【问题描述】:

我有一个直接写入输出流的操作。有时我会遇到以下错误:

Error processing GroovyPageView: getOutputStream() has already been called for this response
Caused by getOutputStream() has already been called for this response

还有这个:

Executing action [getImage] of controller [buddyis.ItemController] caused exception: Runtime error executing action
Caused by Broken pipe

我该如何解决这些问题?下面列出了我使用的操作。

注意:如果这很重要,我使用的是 Tomcat 7.0.42!

def getImage() {
    byte [] imageByteArray = // some image bytes

    response.setHeader 'Content-disposition', "attachment; filename=\"${imageName}${imageExtension}\""
    response.setContentType("image/pjpeg; charset=UTF-8")
    response.contentLength = imageByteArray.size()
    response.outputStream.write(imageByteArray)
    response.outputStream.flush()
    response.outputStream.close()
    return
}

【问题讨论】:

  • 尝试渲染一些东西(虚拟)来索引或渲染状态代码,看看你是否仍然遇到问题。您可以在返回之前以render(status: 200) 或至少render "Done" 等开头。
  • 参考this question

标签: spring grails grails-2.0


【解决方案1】:

我不知道您为什么会收到该错误,但是这是我每次都有效的方法。

我不打电话给.flush().close()

response.setContentType("application/octet-stream")
response.setHeader("Content-disposition", "filename=\"${name}\"")
response.setContentLength(imageByteArray.size())
response.outputStream << imageByteArray

使用上面它工作正常,直到我发现用户可以取消下载,这导致了异常。这是我使用的完整代码,而不是 response.outputStream &lt;&lt; imageByteArray

    def outputStream = null
    try {
        outputStream = response.outputStream
        outputStream << imageByteArray

    } catch (IOException e){
        log.debug('Canceled download?', e)
    } finally {
        if (outputStream != null){
            try {
                outputStream.close()
            } catch (IOException e) {
                log.debug('Exception on close', e)
            }
        }
    }

【讨论】:

  • 我使用的是 Tomcat 7.0.42,如果这对答案很重要?为什么 ContentType “application/octet-stream”?
  • 我想我使用的是 7.0.39,所以这不重要。至于内容类型 - 我允许下载/上传多种类型的文件。这似乎对所有人都有效。
  • 好吧,那么 .flush() 和 .close() 为什么不需要呢?
  • 根据我的经验,谷歌浏览器有时会任意终止连接。所以,我会添加捕获异常::if (e.getClass().name == 'org.apache.catalina.connector.ClientAbortException') { log.warn "请求被客户端任意终止:$e.cause " }
  • @Andiry 添加的是日志记录功能——它的个人偏好。它不会改变它的工作方式。答案应该包含尽可能少的信息以充分回答问题。
【解决方案2】:

我在 tomcat:7.0.55.3 上运行 grails 2.5 并安装了 java-melody grails 插件时遇到了这个问题。卸载 java-melody 后,它工作得很好

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多