需求1:解压某个jar文件输出到某个文件夹。
需求2:对某个文件夹进行打包,生成一个jar文件。
需求3:复制某个jar文件,生成另一个jar文件,jar的内容可能需要进行更改比如做加密等操作。
直接上代码:
import java.io.InputStream;
import java.io.OutputStream;
import java.util.jar.JarEntry;
/**
* jar处理器
*/
@FunctionalInterface
public interface JarFileHandler{
/**
* 处理jar
* 注意:在此处对inputStream的字节流进行加密后,调用closeEntry()时会抛异常:
* java.util.zip.ZipException: invalid entry size (expected 7260 but got 7264 bytes)
* at java.util.zip.ZipOutputStream.closeEntry(ZipOutputStream.java:262)
* @param jarEntry jar条目
* @param inputStream 输入流
* @param outputStream 输出流
* @throws
*/
OutputStream handle(JarEntry jarEntry, InputStream inputStream, OutputStream outputStream) throws Exception;
}
import java.io.InputStream;
import java.io.OutputStream;
import java.util.jar.JarEntry;
/**
* 默认jar处理器,不做任何处理
*/
public class DefaultJarFileHandler implements JarFileHandler{
/**
* 默认jar处理器
*/
private static final JarFileHandler defaultJarFileHandler = new DefaultJarFileHandler();
private DefaultJarFileHandler(){}
/**
* 获取默认jar处理器
* @return
*/
public static JarFileHandler getInstance(){
return defaultJarFileHandler;
}
@Override
public OutputStream handle(JarEntry jarEntry, InputStream inputStream, OutputStream outputStream) throws Exception{
return JarUtil.write(inputStream,outputStream);
}
}
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
/**
* File处理器
*/
@FunctionalInterface
public interface FileHandler {
/**
* 处理文件
* @param file 文件
* @param inputStream 输入流
* @param outputStream 输出流
* @throws
*/
OutputStream handle(File file, InputStream inputStream, OutputStream outputStream) throws Exception;
}
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 默认File处理器,不做任何处理
*/
public class DefaultFileHandler implements FileHandler{
/**
* 默认File处理器
*/
private static final DefaultFileHandler defaultFileHandler = new DefaultFileHandler();
private DefaultFileHandler(){}
/**
* 获取默认File处理器
* @return
*/
public static FileHandler getInstance(){
return defaultFileHandler;
}
@Override
public OutputStream handle(File file, InputStream inputStream, OutputStream outputStream) throws Exception{
return JarUtil.write(inputStream,outputStream);
}
}
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
/**
* 加密File处理器
*/
public class EncryptFileHandler implements FileHandler{
/**
* 需要加密的class文件所在package
*/
private List<String> encryptPackages = Arrays.asList("BOOT-INF/classes/指定的包名1","BOOT-INF/classes/指定的包名2");
@Override
public OutputStream handle(String parentPath, File file, InputStream inputStream, OutputStream outputStream) throws Exception{
parentPath = parentPath.replaceAll("\\\\","/")+"/";
String name = file.getAbsolutePath().substring(parentPath.length()).replaceAll("\\\\","/");
if(name.endsWith(".class")){
for (String encryptPackage : encryptPackages) {
if(name.startsWith(encryptPackage)){
System.out.println("加密:"+name);
CipherService cipherService = new DesCipherServiceImpl();
byte[] data = FileUtil.readData(inputStream);
byte[] encrypt = cipherService.encrypt(data);
outputStream.write(encrypt, 0, encrypt.length);
return outputStream;
}
}
}
return JarUtil.write(inputStream,outputStream);
}
}
/**
* 加解密处理器
*/
public interface CipherService {
/**
* 加密
* @param data
* @return
*/
byte[] encrypt(byte[] data);
/**
* 解密
* @param data
* @return
*/
byte[] decrypt(byte[] data);
}
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.SecureRandom;
public class DesCipherServiceImpl implements CipherService {
private static final byte[] DES_KEY = "12345678".getBytes();
@Override
public byte[] encrypt(byte[] data) {
try {
// DES算法要求有一个可信任的随机数源
SecureRandom sr = new SecureRandom();
DESKeySpec deskey = new DESKeySpec(DES_KEY);
// 创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(deskey);
// 加密对象
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key, sr);
// 加密
return cipher.doFinal(data);
} catch (Exception e) {
throw new RuntimeException("加密错误,错误信息:", e);
}
}
@Override
public byte[] decrypt(byte[] data) {
try {
// DES算法要求有一个可信任的随机数源
SecureRandom sr = new SecureRandom();
DESKeySpec deskey = new DESKeySpec(DES_KEY);
// 创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(deskey);
// 解密对象
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key, sr);
// 解密
return cipher.doFinal(data);
} catch (Exception e) {
throw new RuntimeException("解密错误,错误信息:", e);
}
}
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
public class JarUtil {
/**
* 解压jar
* @param sourceJarFile 原jar
* @param targetDir 解压路径
* @throws Exception
*/
public static void unPackageJar(File sourceJarFile,File targetDir) throws Exception{
if(!sourceJarFile.exists()){
System.err.println("文件"+sourceJarFile.getAbsolutePath()+"不存在");
return;
}
URL url = new URL("jar:file:" + sourceJarFile.getAbsolutePath() + "!/");
JarURLConnection uc = (JarURLConnection) url.openConnection();
JarFile jarFile = uc.getJarFile();
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
String name = jarEntry.getName();
File path = new File(targetDir.getAbsolutePath() +File.separatorChar + name);
if (jarEntry.isDirectory()) {
if(path.exists()){
System.err.println("路径已存在:"+path.getAbsolutePath());
return;
}else {
boolean mkdirs = path.mkdirs();
if (!mkdirs) {
System.err.println("创建路径失败:" + path.getAbsolutePath());
return;
}
}
} else {
System.out.println("读取文件:"+name);
InputStream inputStream = jarFile.getInputStream(jarEntry);
FileOutputStream fos = null;
try {
File parentDir = path.getParentFile();
if(!parentDir.exists()){
boolean mkdirs = parentDir.mkdirs();
if (!mkdirs) {
System.err.println("创建路径失败:" + parentDir.getAbsolutePath());
return;
}
}
fos = new FileOutputStream(path);
write(inputStream, fos);
System.out.println("拷贝文件成功:"+path.getAbsolutePath());
}catch (Exception e){
System.err.println("拷贝文件失败:"+path.getAbsolutePath());
}finally {
if(fos!=null){
fos.close();
}
}
}
}
}
/**
* 打包jar
* @param sourceDir 原文件夹
* @param targetJarFile 目标jar
* @param handler File处理器,可为null
* @throws Exception
*/
public static void packageJar(File sourceDir,File targetJarFile, FileHandler handler) throws Exception{
if(!sourceDir.exists()){
System.err.println("文件夹"+sourceDir.getAbsolutePath()+"不存在");
return;
}
File[] files = sourceDir.listFiles();
if(files==null||files.length==0){
System.err.println("文件夹"+sourceDir.getAbsolutePath()+"为空");
return;
}
if(handler==null){
handler = DefaultFileHandler.getInstance();
}
String parentPath = sourceDir.getAbsolutePath();
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(targetJarFile));
try {
for (File file : files) {
packageJar(parentPath,file,jarOutputStream,handler);
}
}finally {
jarOutputStream.close();
}
}
/**
* 递归遍历文件和文件夹,并打包
* @param parentPath 父文件夹
* @param file 文件或文件夹
* @param jarOutputStream 输出流
* @param handler File处理器,可为null
* @throws Exception
*/
private static void packageJar(String parentPath,File file,JarOutputStream jarOutputStream,FileHandler handler) throws Exception{
String absolutePath = file.getAbsolutePath();
if (file.isDirectory()) {
// jarName必须以/结尾,否则打包后是文件,而不是文件夹
String jarName = absolutePath.substring(absolutePath.indexOf(parentPath)+parentPath.length()+1)+"/";
ZipEntry jarEntry = new JarEntry(jarName);
jarOutputStream.putNextEntry(jarEntry);
jarOutputStream.closeEntry();
System.out.println("打包文件夹成功:"+jarName);
File[] childFiles = file.listFiles();
if(childFiles==null||childFiles.length==0){
return;
}else{
for (File childFile : childFiles) {
packageJar(parentPath,childFile,jarOutputStream,handler);
}
}
} else {
String jarName = absolutePath.substring(absolutePath.indexOf(parentPath)+parentPath.length()+1);
ZipEntry jarEntry = new JarEntry(jarName);
System.out.println("读取文件:"+jarName);
jarOutputStream.putNextEntry(jarEntry);
InputStream inputStream = new FileInputStream(file);
handler.handle(file,inputStream,jarOutputStream);
jarOutputStream.closeEntry();
System.out.println("打包文件成功:"+jarName);
}
}
/**
* 读取原jar,拷贝所有内容到另一个jar
* @param sourceJarFile 原jar
* @param targetJarFile 目标jar
* @param handler jar处理器,可为null
* @throws Exception
*/
@Deprecated
public static void copyJar(File sourceJarFile, File targetJarFile, JarFileHandler handler) throws Exception{
if(!sourceJarFile.exists()){
System.err.println("文件"+sourceJarFile.getAbsolutePath()+"不存在");
return;
}
if(handler==null){
handler = DefaultJarFileHandler.getInstance();
}
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(targetJarFile));
try {
URL url = new URL("jar:file:" + sourceJarFile.getAbsolutePath() + "!/");
JarURLConnection uc = (JarURLConnection) url.openConnection();
JarFile jarFile = uc.getJarFile();
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
String name = jarEntry.getName();
if (jarEntry.isDirectory()) {
jarOutputStream.putNextEntry(jarEntry);
jarOutputStream.closeEntry();
System.out.println("拷贝文件夹成功:"+name);
} else {
System.out.println("读取文件:"+name);
jarOutputStream.putNextEntry(jarEntry);
InputStream inputStream = jarFile.getInputStream(jarEntry);
handler.handle(jarEntry,inputStream,jarOutputStream);
jarOutputStream.closeEntry();
System.out.println("拷贝文件成功:"+name);
}
}
}finally {
jarOutputStream.close();
}
}
/**
* 从输入流读数据,写入到输出流
* @param inputStream 输入流
* @param outputStream 输出流
* @return
* @throws Exception
*/
public static OutputStream write(InputStream inputStream, OutputStream outputStream) throws Exception {
try {
int len = 0;
byte[] b = new byte[1024];
while ((len = inputStream.read(b)) > 0) {
outputStream.write(b, 0, len);
}
outputStream.flush();
}finally {
if(inputStream!=null){
inputStream.close();
}
}
return outputStream;
}
}
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
public class Test1 {
@Test
public void writeJarEntryTest() throws Exception{
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream("D:\\myworkspace\\out.jar"));
//加进一个jar文件
jarOutputStream.putNextEntry(new JarEntry("aaa.jar"));
JarUtil.write(new FileInputStream(new File("D:\\myworkspace\\aaa.jar")),jarOutputStream);
jarOutputStream.closeEntry();
//加进一个jar文件
jarOutputStream.putNextEntry(new JarEntry("bbb.jar"));
JarUtil.write(new FileInputStream(new File("D:\\myworkspace\\bbb.jar")),jarOutputStream);
jarOutputStream.closeEntry();
//加进一个xml文件
jarOutputStream.putNextEntry(new JarEntry("pom.xml"));
JarUtil.write(new FileInputStream("D:\\myworkspace\\pom.xml"),jarOutputStream);
jarOutputStream.closeEntry();
//加进一个文件夹
jarOutputStream.putNextEntry(new JarEntry("testpackage/"));
jarOutputStream.closeEntry();
jarOutputStream.close();
}
@Test
public void unPackageJarTest() throws Exception {
JarUtil.unPackageJar(new File("D:\\myworkspace\\aaa.jar"),
new File("D:\\myworkspace\\aaa"));
}
@Test
public void copyJarTest() throws Exception {
JarUtil.copyJar(new File("D:\\myworkspace\\aaa.jar"),
new File("D:\\myworkspace\\aaa2.jar"),null);
}
@Test
public void packageJarTest() throws Exception {
JarUtil.packageJar(new File("D:\\myworkspace\\aaa\\"),
new File("D:\\myworkspace\\aaa.jar"),null);
}
}
版权声明:本文为u013813491原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。