动态修改jar包中xml的Demo实现

前端之家收集整理的这篇文章主要介绍了动态修改jar包中xml的Demo实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

本实例将讲解动态修改jar包文件中的xml。


功能实现步骤如下:

1、创建临时文件夹,并源文件移动到临时文件夹;

2、将新位置的文件,以二进制方式读取文件文件目录;

3、创建xml文件并进行,并将该文件写入源文件目录的jar中;

4、修改后的文件,会替代源文件的位置,更改后名称与源文件名称相同;

5、删除临时文件

说明如下:

1、移动源文件到临时文件


2、在临时文件位置,创建更新的xml文件


3、将临时文件位置的Canlendar.xml和Canlendar.jar文件写回源文件位置,文件名与仍未移动前的名称


4、删除临时文件



package com.lzq.jar;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.XMLWriter;

public class CalendarDemo{

	/**
	 * @MethodName	: main
	 * @Description	: 测试
	 * @param args
	 */
	public static void main(String[] args) {
		CalendarDemo encyptType = new CalendarDemo();
		try {
			encyptType.updateCalendar("我是修改后的Id");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @MethodName	: updateCalendar
	 * @Description	: 修改包含jar包中的xml配置文件
	 * 1、将源文件移动到tempPath目录下
		2、在源文件里面创建 文件名为 源文件名的文件
		3、将文件从临时文件路径读取到源文件路径下
		4、删除临时文件
	 * @param calendarId
	 * @throws IOException 
	 */
	public void updateCalendar(String calendarId) throws IOException  {
		/**
		 * 1、将源文件移动到tempPath目录下
		 */
		//测试路径
//		String jarfile = "D:\\develop-pj\\gxpt_mgr_pj_calendar_impl\\target\\gxpt_mgr_pj_calendar_impl.jar";
		
		// 获取当前Jar文件名,并对其解码,防止出现中文乱码
		String jarfile = URLDecoder.decode(
				com.lzq.jar.CalendarDemo.class
						.getProtectionDomain().getCodeSource().getLocation()
						.getFile(),"UTF-8");
		
		//文件原地址
		File oldFile = new File(jarfile);
		
		// 临时文件文件夹位置
		String tempPath = jarfile.substring(0,jarfile.lastIndexOf("\\") + 1)
				+ "temp\\config";
		
		//new一个新文件夹
		File fnewpath = new File(tempPath);
		
		//判断文件夹是否存在
		if(!fnewpath.exists())
		fnewpath.mkdirs();
		
		//新文件的全路径
		String tempJarPath = tempPath+"\\"+oldFile.getName();
		
		//将文件移到新文件里
		File fnew = new File(tempJarPath);
		oldFile.renameTo(fnew); 

		/**
		 * 2、在源文件里面创建 文件名为 源文件名的文件
		 */
		JarOutputStream jaros = new JarOutputStream(new FileOutputStream(jarfile));
		JarFile jarf = new JarFile(tempJarPath);
		
		/**
		 * 3、将文件从临时文件路径读取到源文件路径下
		 * 			此处通过判断名称修改文件
		 */
		for (Enumeration<JarEntry> en = jarf.entries(); en.hasMoreElements();) {
			JarEntry entry = en.nextElement();
			InputStream entryIn = null;
			if (entry.getName().equals("config/calendar.xml")) {
				entryIn = (updateXmlFile(tempJarPath,calendarId));
			} else {
				entryIn = jarf.getInputStream(entry);
			}
			jaros.putNextEntry(new JarEntry(entry.getName()));
			byte[] encryData;
			byte[] classData = getByteData(entryIn);
			encryData = classData;
			jaros.write(encryData,encryData.length);
			jaros.closeEntry();
		}
		jarf.close();
		jaros.close();
		
		/**
		 * 4、删除临时文件中的数据
		 */
		File f = new File(tempJarPath);
		 if(f.exists()){
		    f.delete();
	    } 
	}

	/**
	 * @MethodName	: updateXmlFile
	 * @Description	: 创建修改后的xml文件
	 * @param currentJarPath
	 * @param calendarId
	 * @return
	 */
	private InputStream updateXmlFile(String currentJarPath,String calendarId) {
		Document document = DocumentHelper.createDocument(); // 创建文档
		Element calendars = document.addElement("calendars");
		Element calendar = calendars.addElement("calendar");
		InputStream is = null;
		String road = "";
		try {
			/**
			 * 1、取得临时文件的路径: a、获取jar文件的路径 b、创建临时文件的路径
			 * 
			 */
			// 临时文件文件夹位置
			road = currentJarPath.substring(0,currentJarPath.lastIndexOf("\\") );

			// 建立文件夹
			File file = new File(road);
			if (!file.exists()) {// 存该文件夹
				file.mkdirs();// 新建
			}
			String EntryName = "\\calendar.xml";

			// road为新xml的全路径
			road += EntryName;
//			System.out.println("road=" + road);

			/**
			 * 2、根据传过来的Id值,在临时文件目录下,创建新的 xml文件
			 */
			calendar.setAttributeValue("id",calendarId);
			Writer fileWriter = new FileWriter(road);
			XMLWriter xmlWriter = new XMLWriter(fileWriter);
			xmlWriter.write(document); // 写入文件中
			xmlWriter.close();

			/**
			 * 3、将文件路径,以流的形式返回
			 */
			is = new FileInputStream(road);

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
		return is;
	}
	
	/**
	 * @MethodName	: getByteData
	 * @Description	: 读二进制文件
	 * @param is  文件流
	 * @return 
	 * @throws IOException
	 */
	private byte[] getByteData(InputStream is) throws IOException {
		int len;
		int size = 1024;
		byte[] buf;
		if (is instanceof ByteArrayInputStream) {
			size = is.available();
			buf = new byte[size];
			len = is.read(buf,size);
		} else {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			buf = new byte[size];
			while ((len = is.read(buf,size)) != -1)
				bos.write(buf,len);
			buf = bos.toByteArray();
		}
		return buf;
	}
}


本实例展示的是仅仅对jar包中的xml文件修改。还有一些功能为实现,如对jar文件进行读取显示等。这里,大家可以手动打开jar包,查看修改的结果。


不过,这种直接更改jar包中的东西是比较危险的,如果jar包之间存在相互引用的关系,会出现更改失败或者导致服务器出现不明异常。所以使用时需要慎重考虑。

猜你在找的XML相关文章