`
cobo85
  • 浏览: 116956 次
  • 性别: 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 根据javaBean反射自定义导出 excel、xml、pdf、csv

    首先,为JavaBean创建一个对应的XML Schema(XSD),然后使用JAXB将JavaBean对象转换成XML文档。 3. **PDF**:生成PDF文件可以使用iText库。创建一个`Document`对象,然后添加`Paragraph`、`Table`等元素,将...

    xstream 让javabean和xml互相转换

    这篇博客“xstream 让javabean和xml互相转换”深入探讨了如何利用XStream库实现这一功能。 XStream的核心思想是通过反射机制,将Java对象的字段映射到XML的元素和属性,以及反向操作将XML解析回Java对象。它的优势...

    用JOX实现xml和javabean的相互转换

    JOX会根据这些XML元素和属性,通过反射机制调用Java Bean的setter方法来填充对象。 JOX的优势在于其简洁的API和对JavaBeans规范的良好支持。它避免了使用DOM、SAX、JDOM等XML解析器时可能遇到的复杂性,让开发者能...

    xml与javabean之间的相互转换,很方便,导入即可使用

    // 反序列化XML为JavaBean User deserializedUser = (User) xstream.fromXML(xml); System.out.println("Name: " + deserializedUser.getName() + ", Age: " + deserializedUser.getAge()); } } ``` 在上述代码...

    使用xstream实现对JavaBean与xml字符串的互转

    要将JavaBean转换为XML字符串,你需要创建一个XStream实例,然后使用`toXML()`方法。下面是一个简单的示例: ```java import com.thoughtworks.xstream.XStream; public class User { private String name; ...

    [经典]自动将任何javabean封装成xml,返回Element对象

    在Java编程中,将javabean转换为XML是常见的需求,特别是在处理数据交换或存储时。这个主题的核心在于如何利用Java的反射API和DOM(Document Object Model)来实现这一过程。下面我们将深入探讨这个过程,以及相关的...

    xml和bean 互相转换

    2. **转换为XML**:使用JAXB的Marshaller将Bean转换为XML字符串或写入文件。 ```java import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import java.io.File; public class WebController { ...

    xml和bean之间的相互转换源码

    XStream通过反射机制自动处理对象到XML的映射,只需简单的几行代码就可以完成转换。 5. **转换步骤**: - 首先,确保Bean类有正确的getter和setter方法,并添加必要的JAXB注解(如果使用JAXB)。 - 创建`...

    使用Betwixt将XML转为JAVA Bean(内有JAR包)

    本教程将通过一个具体的例子,讲解如何使用Betwixt将XML数据转换为Java Bean,特别是处理XML中相同节点名的情况。 首先,我们需要了解Betwixt的基本概念。Betwixt基于JavaBeans规范,通过反射和注解来实现XML和Java...

    java List XMl转换DEMO

    这通常涉及到Java的反射机制,通过分析XML节点来创建和初始化JavaBean对象。以下是一个简单的实现: 1. 解析XML字符串,得到XML的根元素。 2. 遍历XML的子元素,根据元素的标签名创建对应的JavaBean实例。 3. 使用...

    xstream-1.3.1.jar javabean与xml之间的转化

    它通过反射机制自动检测对象的属性,并将其映射到 XML 结构中。例如,一个简单的 Java 类 `Person` 可以被转换为如下的 XML: ```xml &lt;name&gt;John Doe &lt;age&gt;30 ``` 2. **反序列化:**反之,XStream 可以从 XML ...

    javabean源码

    通过库如Jackson或Gson,JavaBean可以方便地转换为JSON对象,便于前后端数据交换。 7. **JavaBean的局限性**: 虽然JavaBean在很多场景下非常有用,但它也有一些局限性,例如不支持多线程共享,对于复杂业务逻辑...

    xmlutils.zip

    `toXML`方法利用反射遍历JavaBean属性,生成XML字符串;`fromXML`方法则解析XML字符串,根据标签创建JavaBean并设置属性。 8. **注意事项**: - 在处理XML时,需要考虑XML的命名空间(namespace)、属性处理、特殊...

    jaxme-0.3.jar.zip

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

    commons-betwixt-0.5-src.zip_ObjectStringConvert_commons-betwixt_

    例如,你可以通过创建一个`BeanWriter`实例,指定输出的XML流,然后将JavaBean对象传递给它,Betwixt会自动将对象的所有属性转换为XML格式。同样,使用`BeanReader`可以从XML输入流中恢复JavaBean对象。在处理复杂...

    java反射实现Object转json

    对于"java反射实现Object转json"这个主题,我们将深入探讨如何使用反射机制将Java对象转换为JSON格式的数据。 首先,理解JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也...

    动态生成javabean

    例如,当我们需要从数据库获取数据并展示时,可以动态生成对应的JavaBean类,然后使用MyBatis的Mapper接口将查询结果转换为JavaBean对象,再由Spring MVC的Controller返回给前端。 总之,动态生成JavaBean是提高...

    面向CSA算法的片上多核DSP处理器设计.pdf

    在XML到数据库的转换过程中,通过反射机制可以读取XML Schema文档并生成相应的JavaBean对象,这有助于将XML结构映射为面向对象的形式。 2. **DOM4j技术**:DOM4j是一个Java库,用于处理XML文档。它可以解析XML,...

    xstream-1.3.1.zip

    在XStream中,"javabean与xml之间的转化"是通过反射和类型转换机制实现的。每个Java类被映射为一个XML元素,类的属性对应于XML的子元素。默认情况下,字段名作为元素名,字段值作为元素内容。如果需要自定义,可以...

    优雅的对象转换解决方案,为什么更推荐MapStruct呢.docx

    1. **JavaBean转换问题** - 在传统的Java开发中,JavaBean之间的转换通常需要手动编写`set`和`get`方法,这既耗时又容易出错。当需要处理大量属性或字段时,这种手动工作尤其繁琐。 - 使用反射库如Apache的...

Global site tag (gtag.js) - Google Analytics