1. 引言
在实际应用中,例如图片、文档等多个文件需要提供给用户下载,单独下载可能不够便捷,因此我们可以考虑将这些文件进行打包zip压缩,用户只需下载一个压缩文件即可获取全部内容,可以自定义压缩包名,文件夹名。
2. 实现代码
下面是一个使用Spring Boot和Java实现文件批量下载与压缩的控制器类代码示例:
@Slf4j
@RestController
@RequestMapping("/downZip")
public class FileDownZipController {
@GetMapping("/down")
public void downZip(HttpServletResponse response) {
// 模拟文件映射关系,第一个参数文件路径,第二个参数压缩包的文件夹格式及名字,图片路径是随意写的,不是正确路径,记得替换
Map<String, String> fileMapping = new HashMap<>();
fileMapping.put("https://(kaifa)_/20240228/11/09/2c6c7562e66a4b36b635744b775b11c6/17090897877771703664943855.jpg", "第一层b/2-1");
fileMapping.put("https://1706758121101%E7%A4%BA%E4%BE%8B.png", "第一层a/1-1");
fileMapping.put("https://17090897652911703667057237.jpg", "第一层a/1-2");
// 设置响应头信息,指定响应类型为zip文件,设置文件名
try {
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("压缩包名" + ".zip", "UTF-8"));
} catch (IOException e) {
throw new RuntimeException("Error setting response headers", e);
}
// 初始化输出流和压缩流
OutputStream out1 = null;
ZipOutputStream zos = null;
try {
out1 = response.getOutputStream();
zos = new ZipOutputStream(out1);
} catch (IOException e) {
throw new RuntimeException("Error initializing output stream", e);
}
for (Map.Entry<String, String> entry : fileMapping.entrySet()) {
String path = entry.getValue();
// 输出创建文件夹的信息
System.out.println("Creating folder at path: " + path);
// 获取文件名
int lastSlashIndex = entry.getKey().lastIndexOf("/");
String imageName = entry.getKey().substring(lastSlashIndex + 1);
// 对文件名进行URL编码
String encodedImageName = null;
try {
encodedImageName = URLEncoder.encode(imageName, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 构建文件URL,并替换特殊字符
String filePath = entry.getKey().substring(0, lastSlashIndex + 1) + encodedImageName;
filePath = filePath.replace("(", "%EF%BC%88").replace(")", "%EF%BC%89");
// 文件名中的加号替换为%20
imageName = imageName.replace("+", "%20");
try {
// 打开文件流
InputStream in = new URL(filePath).openStream();
// 将文件添加到压缩流中
zos.putNextEntry(new ZipEntry(path + "/" + imageName));
byte[] bytes = new byte[1024];
int len;
while ((len = in.read(bytes)) != -1) {
zos.write(bytes, 0, len);
}
in.close();
} catch (IOException e) {
throw new RuntimeException("Error processing file: " + entry.getKey(), e);
}
}
// 关闭压缩流
try {
zos.close();
} catch (IOException e) {
throw new RuntimeException("Error closing ZipOutputStream", e);
}
}
}
3. 实现说明
- 文件模拟: 通过
Map
存储文件的路径和压缩后的文件夹格式及名字,模拟需要下载和zip压缩的文件集合。 - 响应头设置: 在处理下载请求时,设置响应头信息,包括响应的文件类型和文件名。
- response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("压缩包名" + ".zip", "UTF-8"));这行就是设置压缩包名和文件格式
- 初始化输出流和压缩流: 获取响应输出流并初始化
ZipOutputStream
,用于将文件写入压缩包。 - 遍历文件集合: 遍历文件集合,根据文件URL获取文件内容,并将文件写入压缩流中。
- 关闭压缩流: 在所有文件处理完成后,关闭压缩流。
4. 总结
通过这个简单的示例,我们实现了在Spring Boot应用中使用Java完成文件批量下载与zip压缩。这对于需要提供多个文件下载的需求是一个非常实用的功能,用户可以更方便地获取所需文件,减少了手动下载的操作次数。希望本文对使用Spring Boot实现类似功能的开发者有所帮助。