java反射与xml文件解析

    在项目开发的过程中,遇到了要将日志导出为xml格式和将xml导入到日志数据库中的功能需求,因为项目中存在多种日志形式(这听起来很奇葩是不是?),我实在懒得为每一种日志都写一个方法。想到在开始的设计过程中,将每种的日志都映射为一个pojo,故想到了java的反射机制,也是个好方法,下面的代码只是简单地单元测试了下,不能保证正确,紧供参考。


package com.netauth.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.netauth.constants.Constant;
import com.netauth.orm.OrmUtil;
import com.netauth.pojo.User;

public class XmlUtil {

	private static Logger logger = LoggerFactory.getLogger(XmlUtil.class);

	/**
	 * 根据所传入的pojo对象列表生成xml文件
	 * 
	 * @author song @time 2014年7月15日-上午10:07:45
	 * @param outputPath
	 *            输出的文件夹路径,指定为 System.getProperty("user.dir")+"/logs"
	 * @param objects
	 *            (pojo)对象列表,第一个属性为id
	 * @return
	 */
	public static <T> boolean generateXml(String outputPath, List<T> objects) {

		if ("".equals(outputPath) || null == outputPath) {
			logger.debug("指定的目标文件夹为空");
			return false;
		}
		if (null == objects || 0 == objects.size()) {
			logger.debug("所传的pojo对象列表为空");
			return false;
		}

		String pojoName = objects.get(0).getClass().getSimpleName();
		String rootName = pojoName + "s";

		Element root = new Element(rootName);
		Document doc = new Document(root);
		// 得到当前pojo的运行时的类型
		Class c = objects.get(0).getClass();
		// 得到该类的所有属性名称
		Field[] fields = c.getDeclaredFields();

		if (fields.length == 0) {
			logger.debug("当前实体的属性个数为0");
			return false;
		}
		if (!"id".equals(fields[0].getName())) {
			logger.debug("当前实体的第一个属性名称不为id");
			return false;
		}

		for (int i = 0; i < objects.size(); i++) {

			Object o = objects.get(i);
			// 为节点添加‘id’ 属性
			Element elements = new Element(pojoName);
			elements.setAttribute("id", OrmUtil.getValue(fields[i], o).toString());

			// 为节点添加子子节点
			for (int index = 1; index < fields.length; index++) {

				Element element = new Element(fields[index].getName());
				element.setText(OrmUtil.getValue(fields[index], o).toString());
				elements.addContent(element);
			}

			root.addContent(elements);
		}
		// 设置xml输出格式
		Format format = Format.getPrettyFormat();
		format.setIndent("  ");
		format.setEncoding("UTF-8");

		XMLOutputter outputter = new XMLOutputter(format);
		try {
			// 创建输出文件夹
			File xmlDir = new File(outputPath);
			if (xmlDir.exists()) {
				logger.debug("路径存在:" + outputPath);
			} else {
				xmlDir.mkdirs();
			}
			// 创建输出文件
			Date date = new Date();
			DateFormat f = new SimpleDateFormat("yyMMddhhmmss.S", Locale.US);
			String dataStr = f.format(date);
			File xml = new File(outputPath + "/xml_" + dataStr);
			try {
				xml.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			outputter.output(doc, new FileOutputStream(xml));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}

	public static List<Object> paraseXml(File xmlFile, String basePacketName) {

		// 返回构造好的pojo对象列表
		List<Object> pojos = new ArrayList<Object>();

		SAXBuilder builder = new SAXBuilder(false);
		Document document = null;
		try {
			document = builder.build(xmlFile);
			Element root = document.getRootElement();
			String rootString = root.getName().toString();
			String ObjectName = rootString
					.substring(0, rootString.length() - 1);

			// 保存xml文件中的对象元素
			List<Object> resultList = new ArrayList<Object>();
			try {
				Object object = null;
				Class clazz = null;
				List<String> proName = new ArrayList<String>();
				List<Object> proVal = new ArrayList<Object>();
				try {
					// 得到类型
					clazz = Class.forName(basePacketName + ObjectName);

					// 得到所有的 对象元素 列表
					resultList = root.getChildren(ObjectName);
					// 迭代每隔对象元素
					for (Iterator iterator = resultList.iterator(); iterator
							.hasNext();) {
						Element tempObect = (Element) iterator.next();
						Integer id = Integer.valueOf(tempObect
								.getAttributeValue("id"));

						// 添加第一个id属性的名称-值
						proName.add("id");
						proVal.add(id);
						// 取出其它属性的值
						List<Element> childs = tempObect.getChildren();
						Iterator<Element> it = childs.iterator();
						while (it.hasNext()) {
							Element tempField = (Element) it.next();
							proName.add(tempField.getName());
							proVal.add(tempField.getTextNormalize());
						}
						//创建具体实例
						object = clazz.newInstance();
						OrmUtil.setProperties(proName, proVal, object);
						pojos.add(object);

					}
				} catch (InstantiationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return pojos;
	}

	public static void main(String[] args) {
		User user = new User();
		user.setId(1);
		user.setName("a");
		user.setPassword("aaaa");

		List<User> list = new ArrayList<User>();
		list.add(user);
		// generateXml(System.getProperty("user.dir") + "/logs", list);

		File file = new File(
				"D:\\Net\\workspace\\net_auth2\\logs\\xml_140715104606.1");
		List<Object> list2=paraseXml(file, Constant.POJO_BASE_PACKET_NAME);
		
		for (Iterator iterator = list2.iterator(); iterator.hasNext();) {
			Object object = (Object) iterator.next();
			if(object instanceof User){
				System.out.println(object.toString());
			}
		}
	}

}


 

   下面是OrmUtil工具类中设计的方法:

  /**
     * 得到表的主键
     * 
     * @author felix  @date 2014-3-19 下午1:53:44
     * @param clazz
     * @return
     */
    public static Field getIdField(Class<?> clazz){
    	try {
			return clazz.getDeclaredField("id");
		} catch (Exception e) {
			logger.error(" no id field \t " + clazz ,e);
			throw new IllegalArgumentException(" no id field \t " + clazz);
		}
    }
    
    /**设置一个对象的所有属性值
     *@author song @time 2014年7月15日-下午12:47:31
     *@param proName
     *@param proVal
     *@param o
     */
    public static void setProperties(List<String> proName,
			List<Object> proVal, Object o) {

		Class clazz = o.getClass();
		for (int index = 0; index < proName.size(); index++) {
			try {
				Field field = clazz.getDeclaredField(proName.get(index));
				Method method = clazz.getDeclaredMethod(
						getSetterName(field.getName()),
						new Class[] { field.getType() });
				method.invoke(o, proVal.get(index));
			} catch (Exception e) {
				logger.error(" set properties failed \t " + clazz ,e);
			}
		}
	}
    
    /**设置一个对象的单个属性值
     *@author song @time 2014年7月15日-下午12:49:59
     *@param proName
     *@param proVal
     *@param o
     */
    public static void setProperty(String proName,Object proVal,Object o){
    	
    	Class clazz=o.getClass();
    	try {
			Field field = clazz.getDeclaredField(proName);
			Method method = clazz.getDeclaredMethod(
					getSetterName(field.getName()),
					new Class[] { field.getType() });
			method.invoke(o, proVal);
		} catch (Exception e) {
			logger.error(" set properties failed \t " + clazz ,e);
		}
    }
    /**得到set方法
     *@author song @time 2014年7月15日-下午12:44:03
     *@param propertyName
     *@return
     */
    private static String getSetterName(String propertyName) {
		String method = "set" + propertyName.substring(0, 1).toUpperCase()  
                + propertyName.substring(1);  
        return method; 
	}
    
    /**得到get方法
     *@author song @time 2014年7月15日-下午12:44:46
     *@param propertyName
     *@return
     */
    public static String getGetterName(String propertyName) {  
        String method = "get" + propertyName.substring(0, 1).toUpperCase()  
                + propertyName.substring(1);  
        return method;  
    }  
    
  下面是main的xml文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<Users>
  <User id="1">
    <name>a</name>
    <password>aaaa</password>
  </User>
  <User id="2">
    <name>b</name>
    <password>bbbb</password>
  </User>
</Users>


   不多说了,代码可能很渣,见笑见笑.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值