java压缩包加密上传,解密下载
业务场景
供应商上传投标文件需要进行加密处理,通过链接下载时下载的时加密的文件,而通过系统内访问接口下载时,下载的是解密好的文件。
问题解决思路
1. 首先配置三个保存文件的地址:上传地址,解密地址,再次加密地址(也就是最终地址)
2. 压缩包加密上传思路:上传压缩文件时,首先上传到上传地址进行解压,解压完成后,删除掉上传地址的压缩文件,生成密码保存数据库再次加密压缩到加密地址,并删除掉解压的文件。
3. 压缩包解密下载思路:通过系统外部链接下载时下载的是已经加密好的文件。而通过内部接口下载走解密接口,通过传入的信息,匹配数据库中响应的密码。进行解密并并再次进行无密码压缩。最终返回给用户解密后的压缩文件。
4. 使用工具:zip4j
核心方法
1. 引入依赖
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.2</version>
</dependency>
2. 配置文件上传路径(在yml中配置并在需要使用的类中引入)
/*文件上传路径*/
@Value(value = "${jeecg.path.upload}")
private String uploadpath;
/*压缩包解压路径*/
@Value(value = "${jeecg.path.zipUpFile}")
private String zipUpFile;
/*压缩包上传路径*/
@Value(value = "${jeecg.path.zipFilePath}")
private String zipFilePath;
3. 加密压缩方法(封装到工具类中)
/**
* 加密压缩
*/
public void zipFolderToZip(String extractPath, String filePath, String password) throws Exception {
try {
log.debug("将" + extractPath + "目录下的文件打包并加密");
String path = filePath.substring(0,filePath.lastIndexOf("/"));
File destFile = new File(path);//压缩目录
System.out.println(destFile.isDirectory());
System.out.println(destFile.exists());
destFile.mkdirs();
if (!destFile.isDirectory() && !destFile.exists()) {
destFile.mkdirs();
}
ZipFile zipFile = new ZipFile(filePath);
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
if(password != null){
//是否加密
parameters.setEncryptFiles(true);
//使用标准加密方式
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
//设置加密密钥
parameters.setPassword(password);
}
parameters.setIncludeRootFolder(false);
zipFile.addFolder(extractPath, parameters);
log.debug("将" + extractPath + "目录下的文件打包并加密 成功");
} catch (ZipException e) {
throw new Exception(e.getMessage());
}
}
4. 解密方法(封装到工具类中)
/**
* 解压
*/
public void upzip(File zipFile, String dest, String password) throws Exception {
try {
ZipFile zFile = new ZipFile(zipFile);//指向压缩文件.zip
//设置文件名编码,在gbk系统中需要设置,文件名称是中文就不会乱码
// zFile.setFileNameCharset("GBK");
if (!zFile.isValidZipFile()) {// 检查文件是否合法
throw new Exception("文件名不合法");
}
File destFile = new File(dest);//解压目录
if (destFile.isDirectory() && !destFile.exists()) {
destFile.mkdirs();
}
if (zFile.isEncrypted()) {//如果设置了密码
zFile.setPassword(password.toCharArray());
}
zFile.extractAll(dest);//将文件输出到目标目录
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
2. 加密上传
ZipEncryptUtil zipEncryptUtil = new ZipEncryptUtil();
File file = new File(ctxPath+File.separator+dbpath);
String upPath = zipUpFile+"/"+dbpath;
//将文件解压到该路径下
zipEncryptUtil.upzip(file,upPath,null);
//将文件打包到该路径
String filePath = uploadpath+"/"+dbpath;
zipEncryptUtil.zipFolderToZip(upPath,filePath,password);
//删除上传的压缩文件
zipEncryptUtil.deleteAnyone(ctxPath+"/"+dbpath);
//删除解压后的文件
zipEncryptUtil.deleteAnyone(upPath);
3. 解密下载
//获取解压文件路径
String filePath = uploadpath + File.separator + imgPath;
String downloadFilePath = uploadpath + File.separator + filePath;
//将文件解压到指定路径
File upFile = new File(filePath);
String upPath = zipUpFile+"/"+imgPath;
zipEncryptUtil.upzip(upFile,upPath,businessBidDoc.getFilePassword());
//将文件压缩不加密压缩到指定路径
String finalPath = zipFilePath+"/"+imgPath;
zipEncryptUtil.zipFolderToZip(upPath,finalPath,null);
File file = new File(downloadFilePath);
response.setContentType("application/force-download");// 设置强制下载不打开
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
inputStream = new BufferedInputStream(new FileInputStream(finalPath));
outputStream = response.getOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
response.flushBuffer();
//删除解压的压缩文件
zipEncryptUtil.deleteAnyone(upPath);
//删除解压后重新压缩的文件
zipEncryptUtil.deleteAnyone(finalPath);