You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于现有单文件下载控制器实现多文件下载?避免独立JS请求

多文件单次下载实现方案

HTTP协议规定单次请求只能返回一个响应实体,所以无法直接返回两个独立文件。要避免额外JavaScript请求的话,最优方案是把两个文件打包成ZIP压缩包,通过一次请求返回这个压缩包,用户下载后解压就能得到两个文件。

以下是基于你现有代码改造的Groovy实现:

// 定义要下载的两个文件路径
def file1 = new File("/tmp/file1.txt")
def file2 = new File("/tmp/file2.txt")

// 设置响应头,指定返回ZIP格式
response.setContentType("application/zip")
response.setHeader("Content-disposition", "attachment; filename=combined_files.zip")

// 直接在响应输出流上创建ZipOutputStream,无需临时文件
def zipOutputStream = new java.util.zip.ZipOutputStream(response.outputStream)

// 添加第一个文件到压缩包
zipOutputStream.putNextEntry(new java.util.zip.ZipEntry(file1.name))
zipOutputStream.write(file1.bytes)
zipOutputStream.closeEntry()

// 添加第二个文件到压缩包
zipOutputStream.putNextEntry(new java.util.zip.ZipEntry(file2.name))
zipOutputStream.write(file2.bytes)
zipOutputStream.closeEntry()

// 完成压缩并关闭流
zipOutputStream.finish()
zipOutputStream.close()

注意事项

  • 确保两个目标文件存在,可添加文件存在性检查(如if (!file1.exists())),避免抛出IO异常
  • 如果文件较大,不要一次性读取file.bytes,改用FileInputStream分块写入,避免内存过载:
    def buffer = new byte[4096]
    def inputStream = new FileInputStream(file1)
    int bytesRead
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        zipOutputStream.write(buffer, 0, bytesRead)
    }
    inputStream.close()
    
  • 如果文件名包含中文,需对filename做编码处理,避免浏览器显示乱码,例如:
    def encodedFilename = java.net.URLEncoder.encode("合并文件.zip", "UTF-8")
    response.setHeader("Content-disposition", "attachment; filename=${encodedFilename}")
    

内容的提问来源于stack exchange,提问作者NiBE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 08:37:03