如何基于现有单文件下载控制器实现多文件下载?避免独立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
相关产品推荐
相关产品推荐

