WAR包补丁工具_修改war包配置文件

2022-11-10 15:24:59 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

简要:

因目前处于运维历史悠久的WEB项目中,每次需求开发完成需要更打补丁文件,因此编写打补丁工具,以解决手动查找补丁文件的繁琐且重复操作。纯Java代码编写,使用Swing作为界面UI,原有代码只针对特殊使用场景,可以适当加以修改。

适用:

编译工具:Eclipse Luna Release (4.4.0)

运行环境:JDK 1.7

代码:

界面GUI 部分:使用JSplitPane垂直分割布局方式。

代码语言:javascript复制
public class PatchSwing extends JFrame{
//上部组件
JPanel jp1;	//定义面板
JSplitPane jsp;	//定义拆分窗格
JTextArea jta1;	//定义文本域
JScrollPane jspane1;	//定义滚动窗格
JTextArea jta2;	
JScrollPane jspane2;
JLabel       label;
JTextField textField; 
//下部组件
JPanel jp2;
JButton jb1,jb2;    //定义按钮
JComboBox jcb1;	    //定义下拉框
public PatchSwing() {
//上部组件
jp1=new JPanel();	//创建面板
JPanel jpwar = new JPanel();
label = new JLabel("WAR路径");
textField = new JTextField(20);
textField.setFont(new Font(null, Font.PLAIN, 18));
jpwar.add(label);
jpwar.add(textField);
jta1=new JTextArea();	//创建多行文本框
jta1.setLineWrap(true);	//设置多行文本框自动换行
jta1.setToolTipText("输入需要查找的文件");
jspane1=new JScrollPane(jta1);	//创建滚动窗格
JSplitPane jspwar=new JSplitPane(JSplitPane.VERTICAL_SPLIT,jpwar,jspane1); //创建拆分窗格
jspwar.setDividerLocation(40);	//设置拆分窗格分频器初始位置
jspwar.setDividerSize(1);			//设置分割线的宽度
jta2=new JTextArea();
jta2.setLineWrap(true);
jta2.setToolTipText("显示查询结果");
jspane2=new JScrollPane(jta2);
jsp=new JSplitPane(JSplitPane.VERTICAL_SPLIT,jspwar,jspane2); //创建拆分窗格
jsp.setDividerLocation(300);	//设置拆分窗格分频器初始位置
jsp.setDividerSize(1);			//设置分割线的宽度
//下部组件
jp2=new JPanel();
jb1=new JButton("打开");		//创建按钮
jb2=new JButton("查找");
String [] name= {".class",".js"};
jcb1=new JComboBox(name);	//创建下拉框
//设置布局管理
jp1.setLayout(new BorderLayout());	//设置面板布局
jp2.setLayout(new FlowLayout(FlowLayout.RIGHT));
//添加组件
jp1.add(jsp);
jp2.add(jcb1);
jp2.add(jb1);  	addActionListener(jb1);
jp2.add(jb2);	addActionListener(jb2);
this.add(jp1,BorderLayout.CENTER);
this.add(jp2,BorderLayout.SOUTH);
//设置窗体实行
this.setTitle("PatchTool");		//设置界面标题
this.setIconImage(new ImageIcon("aa.jpg").getImage());    //设置标题图片,就是上面的小企鹅
this.setSize(400, 500);				//设置界面像素
this.setLocation(200, 200);			//设置界面初始位置
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);	//设置虚拟机和界面一同关闭
this.setVisible(true);				//设置界面可视化
}
//添加按钮监听
private void addActionListener(JButton search) {
search.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String btnName = e.getActionCommand();
if(btnName.equals("查找")){
searchBtn();
}else if(btnName.equals("打开")){
openBtn();
}
}
});
}
//查询按钮事件
private void searchBtn(){
String warPath = textField.getText().trim();
String srcFile = jta1.getText().trim();
if(warPath == null || "".equals(warPath))
JOptionPane.showMessageDialog(null, "请输入WAR路径!");
else if(srcFile == null || "".equals(srcFile))
JOptionPane.showMessageDialog(null, "请输入查找文件!");
else if(!new File(warPath).exists())
JOptionPane.showMessageDialog(null, "WAR路径文件不存在!");
else{
if(new File(warPath).isDirectory())
warPath  = "\XXX.war";
srcFile = srcFile.replace("n", ",").replace(".java", ".class");
new PatchFilesGet(warPath, srcFile, jta2);
}
}
//打开按钮事件
private void openBtn(){
String warPath = textField.getText().trim();
if(warPath == null || "".equals(warPath))
JOptionPane.showMessageDialog(null, "请输入WAR路径!");
else if(!new File(warPath).exists())
JOptionPane.showMessageDialog(null, "WAR路径目录不存在!");
else{
try {
if(new File(warPath).isDirectory())
Desktop.getDesktop().open(new File(warPath));
else
Desktop.getDesktop().open(new File(warPath).getParentFile());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new PatchSwing();
}
}

1.粘贴对应路径URL

2.上半部分的框粘贴需要查找的类文件

3.下半部分框显示查询结果

WAR查询逻辑:

代码语言:javascript复制
public class PatchFilesGet {
private String warPath;
JTextArea jta2; //结果输出
public PatchFilesGet(String warPath,String srcFile,JTextArea jta2) {
this.warPath = warPath;
this.jta2 = jta2;
jta2.setText("");
try {
showRes("查询开始...");
getWarFiles(srcFile,warPath);
showRes("查询结束!");
} catch (IOException e) {
e.printStackTrace();
}
}
//查询所有文件
public void getWarFiles(String srcFile,String path) throws IOException{
JarFile war = new JarFile(path);
Enumeration<JarEntry> entries = war.entries(); 
String parentPath = new File(path).getParent() File.separator;
List<File> jarList = new ArrayList<>();
//遍历条目
while (entries.hasMoreElements()) { 
//参考api获取你需要的文件信息
JarEntry element = entries.nextElement();
String name = getFileName(element);
if(name.endsWith(".class")&&srcFile.indexOf(name) != -1){
showRes("文件已找到!" name);
InputStream iw = war.getInputStream(element);
File file = new File(parentPath "/" element);
createPareDir(file);
writeFile(iw, file);
continue;
}
getJarFiles(srcFile, element, war, parentPath, jarList);
}
war.close();
deleteJar(jarList); //删除 查询过程中解压出来的 jar
}
//查询war 中jar文件
public void getJarFiles(String srcFile,JarEntry element,JarFile war,String parentPath,List<File> jarList) throws IOException{
//判断是否为 jar
if(element.getName().endsWith("XXX.jar")){
InputStream in = war.getInputStream(element);
String jarName = getFileName(element);
String par =parentPath  jarName;
File file = new File(par);
writeFile(in, file); //输出 jar文件包
in.close();
if(file.exists() && file.length() > 1L){
jarList.add(file);
JarFile jar = new JarFile(par);
Enumeration<JarEntry> e = jar.entries(); //  遍历jar
while (e.hasMoreElements()) { 
JarEntry ele = e.nextElement();
String eleName = getFileName(ele);
if(eleName.endsWith(".class")&&srcFile.indexOf(eleName) != -1){//找到目标文件
showRes("文件已找到!" eleName);
InputStream ij = jar.getInputStream(ele);
File filec = new File(par.replace("XXX.jar", "") "/" ele.getName());
createPareDir(filec);
writeFile(ij, filec);
}
}
jar.close(); //关闭 jar读取流 否则删除不了  找好久
}
}
}
//写入操作
public void writeFile(InputStream is, File file) throws IOException{
if(file != null){
//推荐使用字节流读取,因为虽然读取的是文件,如果是 .exe, .c 这种文件,用字符流读取会有乱码
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
byte[] bytes = new byte[2048]; //这里用小数组读取,使用file.length()来一次性读取可能会出错(亲身试验)
int len;
while((len = is.read(bytes)) != -1) {
os.write(bytes, 0, len);
}
os.close();
is.close();
}
}
//结束 删除解压出来的 jar 文件
public void deleteJar(List<File> list){
showRes("正在删除冗余文件...");
for (int i = 0; i < list.size(); i  ) {
File file = list.get(i);
if(!file.delete())
showRes("文件删除失败!" file.getName());
}
}
public void createPareDir(File file){
if(!file.getParentFile().exists()){
if(file.getParentFile().mkdirs()){
showRes("创建目录成功!" file.getParentFile());
}else{
showRes("创建目录失败!" file.getParentFile());
}
}
}
//获取文件名
public String getFileName(JarEntry ele){
return ele.getName().substring(ele.getName().lastIndexOf("/") 1);
}
//输出查询结果
private void showRes(String res){
if(jta2 != null){
jta2.setText(jta2.getText()   "n"  res);;
}
}
}

总结:

编写过程中遇到两个问题:1.WAR包中解压出来的jar文件删除失败问题,关闭所有文件读取流 jar.close();2.创建文件夹失败问题,存在同名文件时,使用java创建以文件名为名称的文件夹时失败。

此代码因个人使用,并不是很完善,还有很多功能可以增加完善。比如添加查询文件过滤,文件查询结果统计返回失败、成功数,补丁对比等功能。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/185754.html原文链接:https://javaforall.cn

0 人点赞