【问题标题】:Writing binary content directly to the client bypassing the Grails view layer绕过 Grails 视图层直接将二进制内容写入客户端
【发布时间】:2009-10-31 23:06:28
【问题描述】:

以下动作是为了将bytes的二进制内容完全绕过Grails视图层直接写入客户端:

def actionName = {
  byte[] bytes = ...
  ServletOutputStream out = response.getOutputStream()
  out.write(bytes)
  out.flush()
  out.close()
  return false
}

我的印象是return false 会让 Grails 完全跳过视图层。然而,情况似乎并非如此,因为上面的代码仍然让 Grails 搜索 /WEB-INF/grails-app/views/controllerName/actionName.jsp(由于不存在这样的文件,因此失败并返回 404)。

问题:

  • 鉴于上面的代码,如何在 Grails 中完全绕过视图层?

【问题讨论】:

    标签: grails


    【解决方案1】:

    您应该返回 null 或根本不返回任何内容,这将被解释为 null。以下是发送动态生成的 PDF 的操作的一些工作代码:

    def pdf = {
       byte[] content = ...
       String filename = ...
       response.contentType = 'application/octet-stream'
       response.setHeader 'Content-disposition', "attachment; filename=\"$filename\""
       response.outputStream << content
       response.outputStream.flush()
    }
    

    【讨论】:

    • 嗨,伯特!感谢您的回答和漂亮的代码。但是,代码并没有解决“完全绕过视图层”的问题。请看下面我的回答。你知道为什么需要 response.contentType == null 才能工作吗?是错误还是功能?
    • @Burt Beckwith 总是 response.outputStream.flush() 还是我也必须添加 response.outputStream.close() ?最后返回 null 是什么?
    • @Burt Beckwith 你对这个相关问题有什么想法吗:stackoverflow.com/questions/18658021/…
    【解决方案2】:

    如果response.contentType.startsWith('text/html'),它会在 Grails 尝试渲染视图时出现。这似乎是一个已知错误,请参阅GRAILS-1223

    这里有两种解决方法:

    1. 按照GRAILS-1223 中的建议使用render(contentType: "text/html", text: htmlString)。这将绕过视图层。
    2. 使用response.contentType = '' 清除内容类型。这也将绕过视图层。但是请注意,内容将在没有 Content-Type 的情况下提供给最终用户,这可能会使某些浏览器感到困惑。

    【讨论】:

      猜你喜欢
      • 2013-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多