今天的新需求,希望上传zip包之后进行加密。
虽然java.util里有zip工具类,但是有种种限制,比如不支持中文文件名之类的。于是在网上找轮子,看到 zip4j 感觉不错。
开搞
添加Maven依赖
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.2</version>
</dependency>
为了方便入门,从官网下载了示例
官网:http://www.lingala.net/zip4j/
示例:http://www.lingala.net/zip4j/download.php
示例代码:
基本的使用情景都有了。
api的基本用法大致如下:
1.创建ZipFile对象
2.创建ZipParameters对象,并使用该对象配置属性
3.ZipFIle对象有addFile/addFiles等方法,在此传入File/InputStream/目录 + 配置好的ZipParameters对象即可压缩。
需要加密时在ZipParameters对象中配置对应的参数即可。
看一下加密的例子:
普通加密:
// Set the encryption flag to true
// If this is set to false, then the rest of encryption properties are ignored
parameters.setEncryptFiles(true);
// Set the encryption method to Standard Zip Encryption
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
// Set password
parameters.setPassword("test123!");
AES加密:
// Set the encryption flag to true
// If this is set to false, then the rest of encryption properties are ignored
parameters.setEncryptFiles(true);
// Set the encryption method to AES Zip Encryption
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
// Set AES Key strength. Key strengths available for AES encryption are:
// AES_STRENGTH_128 - For both encryption and decryption
// AES_STRENGTH_192 - For decryption only
// AES_STRENGTH_256 - For both encryption and decryption
// Key strength 192 cannot be used for encryption. But if a zip file already has a
// file encrypted with key strength of 192, then Zip4j can decrypt this file
parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
// Set password
parameters.setPassword("test123!");
看过例子试着写了第一版代码熟悉熟悉:
private Map zipFileWithPass(CommonsMultipartFile file,String filePath,String password) {
Map resultMap = new HashMap();
try {
log.debug("开始zip加密");
//创建zip文件
ZipFile zipFile = new ZipFile(filePath);
//准备压缩参数
ZipParameters parameters = new ZipParameters();
//压缩算法
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
//压缩等级
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
parameters.setIncludeRootFolder(false);
//是否加密
parameters.setEncryptFiles(true);
// //使用AES加密
// parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
// //AES256
// parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
//使用标准加密方式
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
//设置加密密钥
parameters.setPassword(password);
//CommonsMultipartFile 转 File
DiskFileItem diskFileItem = (DiskFileItem)file.getFileItem();
log.debug("diskFileItem.getName()" + diskFileItem.getName());
File normalFile = diskFileItem.getStoreLocation();
log.debug("normalFile.getName()" + normalFile.getName());
//添加到压缩文档
zipFile.addFile(normalFile, parameters);
// zipFile.addStream(in, parameters);
resultMap.put("error", 0);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
log.debug(e.toString());
resultMap.put("error", 1);
resultMap.put("msg", e.getMessage());
}finally {
return resultMap;
}
}
这样初步实现了加密压缩,但是需求中上传的文件已经是zip了,此时的结果是zip包zip。
于是决定改变思路,将文件解压再重压缩:(应该有更好的方法)
private Map unZipFileToFolder(CommonsMultipartFile file, String extractPath) {
Map resultMap = new HashMap();
try {
log.debug("将文件解压到" + extractPath);
DiskFileItem diskFileItem = (DiskFileItem)file.getFileItem();
log.debug("diskFileItem.getName()" + diskFileItem.getName());
File normalFile = diskFileItem.getStoreLocation();
log.debug("normalFile.getName()" + normalFile.getName());
ZipFile zipFile = new ZipFile(normalFile);
zipFile.extractAll(extractPath);
log.debug("将文件解压到" + extractPath + " 成功");
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
log.debug("将文件解压到" + extractPath + " 失败");
}finally {
return resultMap;
}
}
private Map zipFolderToZip(String extractPath, String filePath, String password) {
Map resultMap = new HashMap();
try {
log.debug("将" + extractPath + "目录下的文件打包并加密");
// Initiate ZipFile object with the path/name of the zip file.
ZipFile zipFile = new ZipFile(filePath);
// Initiate Zip Parameters which define various properties such
// as compression method, etc.
ZipParameters parameters = new ZipParameters();
// set compression method to store compression
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
// Set the compression level
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
//是否加密
parameters.setEncryptFiles(true);
// //使用AES加密
// parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
// //AES256
// parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
//使用标准加密方式
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
//设置加密密钥
parameters.setPassword(password);
parameters.setIncludeRootFolder(false);
// Add folder to the zip file
zipFile.addFolder(extractPath, parameters);
// File file = new File(filepath);//File类型可以是文件也可以是文件夹
// File[] fileArray = file.listFiles();
// ArrayList<File> fileList = getAllFilesFromPath(filepath);
// ArrayList<File> fileList = Zip4jUtil.getFilesInDirectoryRec(new File(extractPath), false);
// for(File subfile: fileArray) {
// fileList.add(subfile);
// }
// zipFile.addFiles(fileList, parameters);
log.debug("将" + extractPath + "目录下的文件打包并加密 成功");
} catch (ZipException e) {
e.printStackTrace();
log.debug("将" + extractPath + "目录下的文件打包并加密 失败");
}finally {
return resultMap;
}
}
注意在此压缩时加上
parameters.setIncludeRootFolder(false);
否则zip包内会多套一层目录