最近做流程项目用到了dom4j,于是就对dom4j进行了大概的学习。我做的流程项目是jbpm4的,实现的功能是将流程用到的表从mysql数据库中导出,通过dom4j解析成xml文件,导出到客户端,这是流程的导出;也可以将导出的流程xml文件导入到mysql数据库中。别的不多说,下面我通过一个例子总结我对dom4j的学习。
首先创建一个测试项目dom4jTest,在项目的src目录下面创建一个pojo:Person.java代码如下:
package com.lujinyong.dom4j;
/**
*
* @Description: person类用来测试java反射在dom4j中的使用
* @Author: lujinyong
*/
public class Person {
private int id;// 用户id
private String name;// 用户名称
private String sex;// 性别
private int age;// 年龄
private String address;// 住址
public Person(int id, String name, String sex, int age, String address) {
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
this.address = address;
}
/**这里将setter和getter方法省略了*/
//重新toString()方法
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", sex=" + sex
+ ", age=" + age + ", address=" + address + "]";
}
}
下面是Map和Pojo之间转换的通用方法:MapPojoUtils.java作为工具类
package com.lujinyong.dom4j;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.beanutils.BeanUtils;
/**
*
* @Description: map和pojo之间的转换
* @Author: lujinyong
*/
public class MapPojoUtils {
/**
* 将map转换成对应的Pojo 类
* @param 要转换成的对像
* @param map要转换的map
* @return
*/
public static Object map2Pojo(Object o, Map map) {
Set<Map.Entry<String, Object>> set = map.entrySet();
for (Map.Entry<String, Object> entry : set) {
if (entry.getValue() instanceof java.util.Date) {
Date d = (Date) entry.getValue();
map.put(entry.getKey(), MapPojoUtils.addDate(d, 0));
}
}
BeanUtils bu = new BeanUtils();
try {
bu.populate(o, map);
} catch (Exception e) {
e.printStackTrace();
}
return o;
}
/**
* 将pojo 对像转换成map
* @param obj
* @return
*/
public static Map pojo2Map(Object obj) {
Map hashMap = new HashMap();
Class c = obj.getClass();
Field f[] = c.getDeclaredFields();
Method method;
String fieldName;
for (Field field : f) {
fieldName = field.getName();
try {
method = c.getDeclaredMethod("get"
+ fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1));
hashMap.put(fieldName, method.invoke(obj));
} catch (Throwable e) {
System.err.println(e);
}
}
return hashMap;
}
/**
* 日期递增
* @param currentDate
* @param addNum
* @return
*/
public static Date addDate(Date currentDate,int addNum) {
Calendar calender = Calendar.getInstance();
calender.setTime(currentDate);
calender.add(Calendar.DATE, addNum);
Date date = calender.getTime();
return date;
}
}
因为实际项目中直接用的是数据库,但是在这个例子中为了简单我不是用数据库了,而是创建一个类来模拟数据库:MyDataSource.java
package com.lujinyong.dom4j;
import java.util.ArrayList;
import java.util.List;
/**
*
* @Description:数据源,用了模拟数据库
* @Author: lujinyong
*/
public class MyDataSource {
/**
*
* @Description: 获取10个person信息
* @Auther: lujinyong
*/
public static List<Person> getPersonList() {
List<Person> list = new ArrayList<Person>();
for (int i = 0; i < 10; i++) {
Person p = new Person();
p.setId(i);
p.setName("张三" + i);
p.setSex(((int) (Math.random() * 100)) % 2 == 0 ? "女" : "男");
p.setAge(((int) (Math.random() * 100)));
p.setAddress("中国");
list.add(p);
}
return list;
}
}
以上准备是为最重要的部分dom4j的解析做准备,关键类在下面:Dom4jTest.java
package com.lujinyong.dom4j;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;
/**
*
* @Description: 该类测试dom4j的基本使用
* @Author: lujinyong
*/
public class Dom4jTest {
/**
*
* @Description:将对象转成xml文件
* @Auther: lujinyong
*/
@Test
public void pojo2Xml(){
/**1.创建document*/
Document document = DocumentHelper.createDocument();
/**2.添加根元素*/
Element rootElement = document.addElement("root");
/**3.用反射将person写到xml中*/
List<Person> list = MyDataSource.getPersonList();
for(Person person:list){
rootElement = Dom4jTest.object2Element(rootElement, person, String.valueOf(person.getId()));
}
/**4.将document写到xml中并保存到服务器指定的目录中*/
FileOutputStream xmlOut;
try {
xmlOut = new FileOutputStream(new File("d:/person.xml"));
XMLWriter xmlWriter = new XMLWriter(xmlOut,OutputFormat.createPrettyPrint());
xmlWriter.write(document);
xmlWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* @Description:将对应的对象写到xml中
* @Auther: lujinyong
*/
public static Element object2Element(Element root,Object obj,String id){
try {
//获取Document根元素
Class clazz = obj.getClass();
//获取对象名称
String str = clazz.getName();
String objName = str.substring(str.lastIndexOf(".")+1);
//获取对象元素(以表名为标签的元素),不存在,则创建
Element tableElement = root.element(objName);
if(tableElement == null){
tableElement = root.addElement(objName).addAttribute("id", id);
}
//创建一个节点元素
Element nodeElement = tableElement.addElement("node").addAttribute("id", id);
Field[] fields = clazz.getDeclaredFields();
//遍历属性
for(Field field :fields){
/**拼接出属性对应的getter方法名*/
//获取对象属性
String fieldName = field.getName();
StringBuilder sb = new StringBuilder();
sb.append("get");
sb.append(fieldName.substring(0,1).toUpperCase());
if(fieldName.length()>1){
sb.append(fieldName.substring(1));
}
String getMethodName = sb.toString();
//反射method对象
Method getMethod = obj.getClass().getMethod(getMethodName);
//调用方法获取值
Object fieldValue = getMethod.invoke(obj);
//添加节点子元素元素
Element fieldElement = nodeElement.addElement(fieldName).addAttribute(fieldName, fieldName);
fieldElement.setText(fieldValue==null?"":fieldValue.toString());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return root;
}
/**
*
* @Description: 将xml中的数据转成Person对象
* @Auther: lujinyong
*/
@Test
public void xml2Sql(){
String filePath = "d:/person.xml";
List<Person> list = new ArrayList<Person>();
SAXReader reader = new SAXReader();
try {
/**1.读取xml文件,生成document*/
Document document = reader.read(new File(filePath));
/**2.将xml的流程节点信息保存到节点表中*/
List<Element> nodeList = document.getRootElement().element("Person").elements("node");
Map<String,Object> map = new HashMap<String, Object>();
for(Element e : nodeList){
List<Element> temp = e.elements();
for(Element t : temp){
map.put(t.getName(), t.getText());
}
Person person = (Person) MapPojoUtils.map2Pojo(new Person(), map);
list.add(person);
}
for(Person p : list){
System.out.println(p.toString());
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
运行pojo2Xml()方法,则在d盘中会创建一个person.xml文件,打开文件,文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Person id="0">
<node id="0">
<id id="id">0</id>
<name name="name">张三0</name>
<sex sex="sex">女</sex>
<age age="age">1</age>
<address address="address">中国</address>
</node>
<node id="1">
<id id="id">1</id>
<name name="name">张三1</name>
<sex sex="sex">男</sex>
<age age="age">0</age>
<address address="address">中国</address>
</node>
<node id="2">
<id id="id">2</id>
<name name="name">张三2</name>
<sex sex="sex">女</sex>
<age age="age">66</age>
<address address="address">中国</address>
</node>
<node id="3">
<id id="id">3</id>
<name name="name">张三3</name>
<sex sex="sex">女</sex>
<age age="age">44</age>
<address address="address">中国</address>
</node>
<node id="4">
<id id="id">4</id>
<name name="name">张三4</name>
<sex sex="sex">男</sex>
<age age="age">50</age>
<address address="address">中国</address>
</node>
<node id="5">
<id id="id">5</id>
<name name="name">张三5</name>
<sex sex="sex">男</sex>
<age age="age">67</age>
<address address="address">中国</address>
</node>
<node id="6">
<id id="id">6</id>
<name name="name">张三6</name>
<sex sex="sex">女</sex>
<age age="age">25</age>
<address address="address">中国</address>
</node>
<node id="7">
<id id="id">7</id>
<name name="name">张三7</name>
<sex sex="sex">女</sex>
<age age="age">53</age>
<address address="address">中国</address>
</node>
<node id="8">
<id id="id">8</id>
<name name="name">张三8</name>
<sex sex="sex">男</sex>
<age age="age">84</age>
<address address="address">中国</address>
</node>
<node id="9">
<id id="id">9</id>
<name name="name">张三9</name>
<sex sex="sex">男</sex>
<age age="age">94</age>
<address address="address">中国</address>
</node>
<node id="10">
<id id="id">10</id>
<name name="name">张三10</name>
<sex sex="sex">女</sex>
<age age="age">48</age>
<address address="address">中国</address>
</node>
</Person>
</root>
运行xml2Sql()方法,则可以将d盘中创建的person.xml文件进行解析,并转成POJO,此时如果有数据库就可以将转成的POJO保存的数据库中了。
总结一下,该例子中用到的重要知识点:java的反射,dom4j解析。
还有一个比较实用的工具类Map和POJO之间的转化。
永久链接:
http://kevin12.iteye.com/blog/1940281