大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE稳定放心使用
简要:
因目前处于运维历史悠久的WEB项目中,每次需求开发完成需要更打补丁文件,因此编写打补丁工具,以解决手动查找补丁文件的繁琐且重复操作。纯Java代码编写,使用Swing作为界面UI,原有代码只针对特殊使用场景,可以适当加以修改。
适用:
编译工具:Eclipse Luna Release (4.4.0)
运行环境:JDK 1.7
代码:
界面GUI 部分:使用JSplitPane垂直分割布局方式。
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查询逻辑:
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创建以文件名为名称的文件夹时失败。
此代码因个人使用,并不是很完善,还有很多功能可以增加完善。比如添加查询文件过滤,文件查询结果统计返回失败、成功数,补丁对比等功能。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/185754.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...