有时候我们会存在这样的需求?
比如,返回一个数据给移动端,但需要对数据进行压缩。大压缩包里面包含N多个小压缩包。类似于:
parent.zip
-> child.zip
-> child.zip
这种方式和我们之前遇到的,可能只有一级的压缩不太一样。
刚好之前做过类似的需求,话不多说,直接上代码。
首先是Controller里面:
/**
*
* 获取zip文件
*
*/
@GetMapping("/get-zip")
public void getZip(
HttpServletResponse response) {
String fileName = "xxx_file";
byte[] data = genData();
try {
genZip(response, data, fileName);
} catch (IOException e) {
log.error(
"发生异常,异常信息: {}",
e.getMessage());
e.printStackTrace();
}
}
接着还是Controller里面:
/**
* 生成数据.
*
*/
public byte[] genData() throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(outputStream);
try{
// 给压缩文件中添加多个文件,可以设置文件名.
Collections.emptyList().forEach(
item -> {
Random random=new Random();
int id=random.nextInt();
String fileName =
item + "_" + id + ".json";
try {
// 设置文件名
zipOut.putNextEntry(new ZipEntry(fileName));
// 添加文件内容
zipOut.write(fileName.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
log.error(
"获取数据失败,失败原因: {}",
e.getMessage());
e.printStackTrace();
}
});
} finally {
try {
zipOut.closeEntry();
zipOut.close();
outputStream.close();
} catch (IOException e) {
log.error(
"关闭数据压缩失败,失败原因: {}",
e.getMessage());
e.printStackTrace();
}
}
return outputStream.toByteArray();
}
接着是工具类或者?
还是Controller里面:
/**
* 压缩文件输出.
*
* @param response 响应
* @param data 数据
* @param fileName 文件名
* @throws IOException IO异常
*/
private void outZip(HttpServletResponse response, byte[] data, String fileName)
throws IOException {
response.reset();
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + ".zip\"");
response.addHeader("Content-Length", "" + data.length);
response.setContentType("application/octet-stream; charset=UTF-8");
org.apache.commons.io.IOUtils.write(data, response.getOutputStream());
}
大功告成~
下课