前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WAR包补丁工具_修改war包配置文件

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

作者头像
全栈程序员站长
发布2022-11-10 15:24:59
1.6K0
发布2022-11-10 15:24:59
举报
文章被收录于专栏:全栈程序员必看

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

简要:

因目前处于运维历史悠久的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();
}
}
WAR包补丁工具_修改war包配置文件
WAR包补丁工具_修改war包配置文件

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月5日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简要:
  • 适用:
  • 代码:
  • 总结:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档