`
cobo85
  • 浏览: 115139 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

利用反射机制JavaBean转换为XML

    博客分类:
  • J2SE
阅读更多

       发一个刚参加工作时候写的利用dom4j把JavaBean转换为XML的工具类,现在看起来有些地方有些笨拙了,并且xml并不是特别的符合XML的规范,只是做为一般的数据载体使用。功能实现主要是利用反射机制和递归。

 

代码:

     

import java.lang.reflect.Field;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Date;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
/**
 * 
 * 
 * @version   v1.0
 * date:  2008-04-24
 */
public  class Beans2Xml {
	/**
	 * 返回处理后的结果,如果需要处理请在子类里面重载此方法
	 * 
	 * @param propertyName
	 *            属性名称
	 * @param value
	 *            属性值,传的是object类型到应用中自己在进行处理/转换为相应的数值类型
	 * @return 返回处理后的结果,如果为null则删除文档此节点
	 */
	public  String propertyHandler(String propertyName, Object value){
		
		return null;
	}

	/**
	 * 此方法用来解决实体中还有实体set或者实体属性,用递归来实现
	 * 
	 * @param obj
	 *            要生成XML的实体对象
	 * @param customSet
	 *            用于用户自己自定义要处理的实体属性,例如不需要生成某项或者要对某项进行特出的处理都需要放到此SET里面如果没有需要处理的传入new
	 *            set()
	 * @param beanType
	 *            用于实体里面有属性为其他实体的时候,需要传入包名进行判断属性是不是实体例如(com.xxx)传如前两个即可。如实体里面只有简单的java元数据类型此参数请传入null
	 * @param element
	 *            节点元素
	 * @param partent
	 *            用于判断关联关系,例如主单里面有明细,明细里面又有主单的属性
	 * @return 生成的XML文档
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InstantiationException
	 * @throws Exception
	 */
	protected void objectRecursion(Object obj, Set<String> customSet,String beanType, Element element, String partent)
			throws IllegalArgumentException, IllegalAccessException {
		
		Class classType = obj.getClass();
		
		Field[] fileds = classType.getDeclaredFields();// 得到实体的所有属性
		
		String entityName = classType.getSimpleName();
		
		Element entityElement = element.addElement(entityName);

		Element cellElement = null;

		for (int i = 0; i < fileds.length; i++) {

			Field field = fileds[i];
			
			field.setAccessible(true);// 设置private的属性值可以读取
			
			String fieldName = field.getName();

			cellElement = entityElement.addElement("cell");

			cellElement.addAttribute("name", fieldName);

			Object value = field.get(obj);

			if (!customSet.contains(fieldName)) {
				
				if (value != null) {
					
					String tempType = field.getType().getCanonicalName();
					
					if (beanType == null||(!tempType.startsWith(beanType))) {//只要不是自定义的属性类型都走此过程
						
						if (value instanceof Date) {
							
							if (!(value instanceof Time)) {
								
								cellElement.addText(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value));
							
							} else {
								
								cellElement.addText(new SimpleDateFormat("HH:mm:ss").format(value));
								
							}
						} else if (value instanceof List) {// 若为list类型装换为一个以‘,’分隔的字符串
							
							StringBuffer tempString = new StringBuffer();
							
							List tempList = (List) value;
							
							for (int j = 0; j < tempList.size(); j++) {
								
								tempString.append(tempList.get(j) + ",");
							
							}
							
							cellElement.addText(tempString.toString());
							
						} else if (value instanceof Set) {
							
							Set tempSet = (Set) value;
							
							Element setElement =entityElement.addElement(fieldName);
							//此方法只处理自己定义的类型,若为元数据类型或者其他更复杂的set类型请自己进行处理
							for (Iterator iter = tempSet.iterator(); iter.hasNext();) {
								
								Object object = (Object) iter.next();
								
								partent = classType.getName();// 给出包含set集的实体类型防止出现死循环(一旦set实体里面的属性有实体类型,就会出现死循环,最常见的是关联的时候)
								
								objectRecursion(object, customSet, beanType,setElement, partent);
							}
							
							cellElement.detach();//删除具有set属性的元素,因现在它已经变成一个节点
						
						} else {
							
							cellElement.addText(value.toString());
						
						}

					} else {
						
						if (beanType != null && tempType.startsWith(beanType)) {
							
							if (tempType.equals(partent))
								continue;//防止关联出现死循环
							
							objectRecursion(value, customSet, beanType,entityElement, partent);
						
						}
					
					}

				} else {
					
					cellElement.addText("");
				
				}
			} else {
				
				if (value != null) {
					
					String reValue = propertyHandler(fieldName, value);
					
					if (reValue == null) {
						
						cellElement.detach();
					
					} else {
						
						cellElement.addText(propertyHandler(fieldName, value));
					
					}
				} else {
					
					cellElement.addText("");
				
				}

			}

		}

	}

	/**
	 * 此方法生成一个以实体的名字为节点,节点下面的元素name为实体属性,内容为实体的value的XML文档
	 * 
	 * @param headMap
	 *            用户自己定义的XML属性,要以map的方式处理key=属性名称 value=属性值
	 * @param obj
	 *            要生成XML的实体对象
	 * @param customSet
	 *            用于用户自己自定义要处理的实体属性,例如不需要生成某项或者要对某项进行特出的处理都需要放到此SET里面如果没有需要处理的传入new
	 *            set()
	 * @param beanType
	 *            用于实体里面有属性为其他实体的时候,需要传入包名进行判断属性是不是自定义类型(实体)例如(com.xxx)传如前两个即可。如实体里面只有简单的java元数据类型此参数请传入null
	 * @return 生成的XML文档
	 */
	public String entityXmlAssembler(Map headMap, Object obj,Set<String> customSet, String beanType) {

		Document document = DocumentHelper.createDocument();
		
		Element rootElement = document.addElement("root");// 创建以root命名的根节点
		
		Element headElement = rootElement.addElement("head");// 属性头节点
		
		Element propertyElement = null;
		// 生成用户自定义的XML属性
		for (Iterator iterator = headMap.keySet().iterator(); iterator.hasNext();) {

			propertyElement = headElement.addElement("property");// 属性节点

			String propertyString = (String) iterator.next();

			propertyElement.addAttribute("name", propertyString);

			propertyElement.addText(headMap.get(propertyString).toString());

		}
		
		Element bodyElement = rootElement.addElement("body");
		
		try {
			
			this.objectRecursion(obj, customSet, beanType, bodyElement, "");//第一次进行递归无需关联关系
		
		} catch (IllegalArgumentException e) {

			e.printStackTrace();
		
		} catch (IllegalAccessException e) {

			e.printStackTrace();
		
		}

		document.setXMLEncoding("gb2312");
		
		return document.asXML();
	}
}

 

里面的beanType是完全可以去掉的,代码还能写的更优雅一些,现在懒的在修改了,贴出来以供参考。

分享到:
评论

相关推荐

    java List XMl转换DEMO

    java List XMl转换DEMO List2XML 可指定导出字段 XML2List 采用JAVA反射机制讲XML转换成JAVABEAN

    jaxme-0.3.jar.zip

    Ø 反之亦然,解析器将JavaBean转换成原始的XML文档 l 在JaxMe应用中,生成的类也可以: Ø 存储JavaBean到数据库中,可以是XML数据库,如eXist、Xindice、Tamino,也可以是关系数据库,如MySQL Ø 在数据库中...

    基于Java的XML解析与反射设计模式.doc

    xstream可以完美转换xml,与以往的解析xml工具dom相比,xstream是一个易用的、开源 的库,使用起来简单、小巧,容易理解,可以轻易的将java对象和xml文档相互转换,而 且可以修改某个特定的属性和节点名称。...

    Java开发常用jar包

    1.commons-beanutils.jar:提供对Java反射和自省API的包装,主要提供了对于 JavaBean进行各种操作。提供了对于JavaBean进行各种操作,克隆对象,属性等等. 2.commons-digester.jar:方便地将XML文档所定义的元素转化为...

    +Flex+集成到+Java+EE+应用程序的最佳实践(完整源代码)

    资源简介现有的 Java EE ...由于 BlazeDS 需要将 Java 接口 FlexService 暴露给 Flex 前端,因此,我们在配置文件 remoting-config.xml 中将 FlexService 接口声明为一个服务: 清单 6. 定义 flexService 服务 ...

    将 Flex 集成到 Java EE 应用程序的最佳实践(完整源代码)

    现有的 Java EE 应用 ...由于 BlazeDS 需要将 Java 接口 FlexService 暴露给 Flex 前端,因此,我们在配置文件 remoting-config.xml 中将 FlexService 接口声明为一个服务: 清单 6. 定义 flexService 服务 ...

    Spring.3.x企业应用开发实战(完整版).part2

    3.2.3 Java反射机制 3.3 资源访问利器 3.3.1 资源抽象接口 3.3.2 资源加载 3.4 BeanFactory和ApplicationContext 3.4.1 BeanFactory介绍 3.4.2 ApplicationContext介绍 3.4.3 父子容器 3.5 Bean的生命周期 3.5.1 ...

    Spring3.x企业应用开发实战(完整版) part1

    3.2.3 Java反射机制 3.3 资源访问利器 3.3.1 资源抽象接口 3.3.2 资源加载 3.4 BeanFactory和ApplicationContext 3.4.1 BeanFactory介绍 3.4.2 ApplicationContext介绍 3.4.3 父子容器 3.5 Bean的生命周期 3.5.1 ...

    Java2核心技术.part5

    10.1.3将应用程序转换为applet lO.1.4 applet的生命周期 10.1.5安全基础 10.1.6 applet中的弹出式窗口 10.2 applet的HTML标记和属性 11.5.1启用和禁用断言 11.5.2使用断言的建议 11.6调试技术 ...

    Java2核心技术.part3

    10.1.3将应用程序转换为applet lO.1.4 applet的生命周期 10.1.5安全基础 10.1.6 applet中的弹出式窗口 10.2 applet的HTML标记和属性 11.5.1启用和禁用断言 11.5.2使用断言的建议 11.6调试技术 ...

    Java2核心技术.part1

    10.1.3将应用程序转换为applet lO.1.4 applet的生命周期 10.1.5安全基础 10.1.6 applet中的弹出式窗口 10.2 applet的HTML标记和属性 11.5.1启用和禁用断言 11.5.2使用断言的建议 11.6调试技术 11. ...

    Java2核心技术.part6

    10.1.3将应用程序转换为applet lO.1.4 applet的生命周期 10.1.5安全基础 10.1.6 applet中的弹出式窗口 10.2 applet的HTML标记和属性 11.5.1启用和禁用断言 11.5.2使用断言的建议 11.6调试技术 ...

    Java2核心技术.part4

    10.1.3将应用程序转换为applet lO.1.4 applet的生命周期 10.1.5安全基础 10.1.6 applet中的弹出式窗口 10.2 applet的HTML标记和属性 11.5.1启用和禁用断言 11.5.2使用断言的建议 11.6调试技术 ...

    Java2核心技术.part2

    10.1.3将应用程序转换为applet lO.1.4 applet的生命周期 10.1.5安全基础 10.1.6 applet中的弹出式窗口 10.2 applet的HTML标记和属性 11.5.1启用和禁用断言 11.5.2使用断言的建议 11.6调试技术 ...

    FreeMarker模板引擎-其他

    你可以使用抽象(接口)方式表示对象(JavaBean、XML文档、SQL查询结果集等等),告诉模板开发者使用方法,使其不受技术细节的打扰 4、为Web准备 在模板语言中内建处理典型Web相关任务(如HTML转义)的结构 能够集成...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例160 利用反射重写toString()方法 208 实例161 反射与动态代理 209 7.3 常见的未检查型异常 210 实例162 算数异常 210 实例163 数组存值异常 211 实例164 数组下标越界异常 212 实例165 空指针异常 213 7.4 常见...

Global site tag (gtag.js) - Google Analytics