绕过Grails视图层直接将二进制内容写入客户端

绕过Grails视图层直接将二进制内容写入客户端,grails,Grails,以下操作旨在完全绕过Grails视图层,直接将字节的二进制内容写入客户端: def actionName = { byte[] bytes = ... ServletOutputStream out = response.getOutputStream() out.write(bytes) out.flush() out.close() return false } 我的印象是returnfalse会让Grails完全跳过视图层。然而,情况似乎并非如此,因为上面的代码仍

以下操作旨在完全绕过Grails视图层,直接将
字节的二进制内容写入客户端:

def actionName = {
  byte[] bytes = ...
  ServletOutputStream out = response.getOutputStream()
  out.write(bytes)
  out.flush()
  out.close()
  return false
}
我的印象是
returnfalse
会让Grails完全跳过视图层。然而,情况似乎并非如此,因为上面的代码仍然让Grails搜索
/WEB-INF/Grails app/views/controllerName/actionName.jsp
(404失败,因为不存在这样的文件)

问题:

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

您应该返回null或nothing,这将被解释为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()
}
def pdf={
字节[]内容=。。。
字符串文件名=。。。
response.contentType='application/octet stream'
response.setHeader“内容处置”,“附件;文件名=\”$filename“

response.outputStream如果
response.contentType.startsWith('text/html')
,Grails将尝试呈现视图。这似乎是一个已知的错误,请参阅

以下是两个解决方法:

  • 按照中的建议使用
    render(contentType:“text/html”,text:htmlString)
    。这将绕过视图层
  • 使用
    response.contentType=''
    清除内容类型。这也将绕过视图层。但是,请注意,内容将提供给最终用户,而不提供内容类型,这可能会混淆某些浏览器

  • 嗨,伯特!谢谢你的答案和漂亮的代码。但是,代码并没有解决“完全绕过视图层”的问题。请看下面我的答案。你知道为什么response.contentType==null才能工作吗?这是一个bug还是一个功能?@Burt Beckwith它是始终响应。outputStream.flush()还是我必须添加response.outputStream.close()还有?结尾的return null是什么?@Burt Beckwith你对这个相关问题有什么想法吗: