Dom4j/Jaxb2/XStream实现Bean与xml互转

本文介绍三种将JavaBean与XML互相转换的方法:Dom4j、Jaxb2和XStream,包括各自的实现原理、核心类及注解,并提供具体实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Dom4j实现Bean与xml互转

package com.its.test.util.xml;

import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

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

class User {

	private String name;
	private String age;
	private String sex;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAge() {
		return age;
	}
	public void setAge(String age) {
		this.age = age;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}

}

public class Dom4jTest<T> {
	
	/**
	 * DMO4J写入XML
	 * @param obj 泛型对象
	 * @param entityPropertys 泛型对象的List集合
	 * @param Encode XML自定义编码类型(推荐使用GBK)
	 * @param XMLPathAndName  XML文件的路径及文件名
	 */
	public void object2Xml(T obj, List<T> entityPropertys, String Encode, String XMLPathAndName) {
		try {
			long lasting = System.currentTimeMillis();// 效率检测
			XMLWriter writer = null;// 声明写XML的对象
			OutputFormat format = OutputFormat.createPrettyPrint();
			format.setEncoding(Encode);// 设置XML文件的编码格式

			String filePath = XMLPathAndName;// 获得文件地址
			File file = new File(filePath);// 获得文件

			if (file.exists()) {
				file.delete();
			}
			// 新建user.xml文件并新增内容
			Document document = DocumentHelper.createDocument();
			String rootname = obj.getClass().getSimpleName();// 获得类名
			Element root = document.addElement(rootname + "s");// 添加根节点
			Field[] properties = obj.getClass().getDeclaredFields();// 获得实体类的所有属性

			for (T t : entityPropertys) { // 递归实体
				Element secondRoot = root.addElement(rootname); // 二级节点
				for (Field field : properties) {
					// 反射get方法
					String getStr = "get" + field.getName().substring(0, 1).toUpperCase()
							+ field.getName().substring(1);
					Method meth = t.getClass().getMethod(getStr);
					// 为二级节点添加属性,属性值为对应属性的值
					secondRoot.addElement(field.getName()).setText(meth.invoke(t).toString());
				}
			}
			// 生成XML文件
			writer = new XMLWriter(new FileWriter(file), format);
			writer.write(document);
			writer.close();
			long lasting2 = System.currentTimeMillis();
			System.out.println("写入XML文件结束,用时" + (lasting2 - lasting) + "ms");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("XML文件写入失败");
		}

	}
	
	/**
	 * DMO4J XML To Object
	 * @param XMLPathAndName XML文件的路径和地址
	 * @param t 泛型对象
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<T> xml2Object(String XMLPathAndName, T t) {
		long lasting = System.currentTimeMillis();// 效率检测
		List<T> list = new ArrayList<T>();// 创建list集合
		try {
			File f = new File(XMLPathAndName);// 读取文件
			SAXReader reader = new SAXReader();
			Document doc = reader.read(f);// dom4j读取
			Element root = doc.getRootElement();// 获得根节点
			Element foo;// 二级节点
			Field[] properties = t.getClass().getDeclaredFields();// 获得实例的属性
			// 实例的set方法
			Method setmeth;
			// 遍历 t.getClass().getSimpleName()节点
			for (Iterator i = root.elementIterator(t.getClass().getSimpleName()); i.hasNext();) {
				foo = (Element) i.next();// 下一个二级节点
				t = (T) t.getClass().newInstance();// 获得对象的新的实例

				for (Field field : properties) {// 遍历所有节点

					// 实例的set方法
					String setStr = "set" + field.getName().substring(0, 1).toUpperCase()
							+ field.getName().substring(1);
					Class<?> type = field.getType();
					setmeth = t.getClass().getMethod(setStr, type);
					// properties[j].getType()为set方法入口参数的参数类型(Class类型)
					String name = field.getName();
					String value = foo.elementText(name);
					setmeth.invoke(t, value);
					// 将对应节点的值存入
				}
				list.add(t);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		long lasting2 = System.currentTimeMillis();
		System.out.println("读取XML文件结束,用时" + (lasting2 - lasting) + "ms");
		return list;
	}

	public static void main(String[] args) {
		String path = "D:/user.xml";
		Dom4jTest<User> d = new Dom4jTest<User>();
		User bean = new User();
		bean.setName("Test");
		bean.setAge("20");
		bean.setSex("1");
		List<User> users = new ArrayList<User>();
		users.add(bean);
		users.add(bean);
		d.object2Xml(bean, users, "GBK", path);

		User user = new User();
		List<User> list = d.xml2Object(path, user);
		System.out.println("XML文件读取结果");
		for (int i = 0; i < list.size(); i++) {
			User usename = (User) list.get(i);
			System.out.println("name" + usename.getName());
			System.out.println("age" + usename.getAge());

		}
	}
}

 二、Jaxb2实现Bean与xml互转

 1、重要类说明

JAXBContext类,是应用的入口,用于管理XML/Java绑定信息。

Marshaller接口,将Java对转化为XML数据。

Unmarshaller接口,将XML转化为Java对象。

@XmlType,将Java类或枚举类型映射到XML模式类型

@XmlAccessorType(XmlAccessType.FIELD) ,控制字段或属性的序列化。FIELD表示JAXB将自动绑定Java类中的每个非静态的(static)、

非瞬态的(由@XmlTransient标 注)字段到XML。其他值还有XmlAccessType.PROPERTY和XmlAccessType.NONE。

@XmlAccessorOrder,控制JAXB 绑定类中属性和字段的排序。

@XmlJavaTypeAdapter,使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML。

@XmlElementWrapper ,对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的XML元素(称为包装器)。

@XmlRootElement,将Java类或枚举类型映射到XML元素。

@XmlElement,将Java类的一个属性映射到与属性同名的一个XML元素。

@XmlAttribute,将Java类的一个属性映射到与属性同名的一个XML属性。

2、实例

2.1、JavaBean

import java.util.Date;
import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import com.tzz.util.xml.JaxbDateSerializer;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "country")
@XmlType(propOrder = { "id", "createDate", "name", "provinceList" })
public class Country {

	private Integer id;
	@XmlJavaTypeAdapter(JaxbDateSerializer.class)
	private Date createDate;
	@XmlElement(name = "name")
	private String name;
	@XmlElementWrapper(name = "provinces")
	@XmlElement(name = "province")
	private List<Province> provinceList;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<Province> getProvinceList() {
		return provinceList;
	}

	public void setProvinceList(List<Province> provinceList) {
		this.provinceList = provinceList;
	}
}
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = { "name", "provCity" })
public class Province {

	@XmlElement(name = "name")
	private String name;
	@XmlElement(name = "provCity")
	private String provCity;

	public String getProvCity() {
		return provCity;
	}

	public void setProvCity(String provCity) {
		this.provCity = provCity;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

 2.2、转化工具类

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

/**
 * Jaxb 2.0
 *
 */
public class JaxbXmlUtil {

	@SuppressWarnings("unchecked")
	public static <T> T xmlToBean(String xml, Class<T> beanClass) {
		try {
			JAXBContext jaxbContext = JAXBContext.newInstance(beanClass);
			Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
			T user = (T) unmarshaller.unmarshal(new StringReader(xml));
			return user;
		} catch (JAXBException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**Bean转XML*/
	public static String beanToXml(Object obj) {
		String result = null;
		try {
			JAXBContext context = JAXBContext.newInstance(obj.getClass());
			Marshaller marshaller = context.createMarshaller();
			//决定是否在转换成xml时同时进行格式化(即按标签自动换行,否则即是一行的xml)
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			//Marshaller.JAXB_ENCODING xml的编码方式
			marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
			StringWriter writer = new StringWriter();
			marshaller.marshal(obj, writer);
			result = writer.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
}

 2.3、测试类

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.junit.Test;

import com.tzz.test.util.xml.entity.Country;
import com.tzz.test.util.xml.entity.Province;
import com.tzz.util.xml.JaxbXmlUtil;

public class TestJaxbBeanToXmlUtil {

	@Test
	public void testBeanToXml() {
		Country country = new Country();
		country.setId(1);
		country.setCreateDate(new Date());
		country.setName("中国");
		
		List<Province> list = new ArrayList<Province>();
		Province province = new Province();
		province.setName("广东省");
		province.setProvCity("广州市");
		Province province2 = new Province();
		province2.setName("湖南省");
		province2.setProvCity("长沙市");
		list.add(province);
		list.add(province2);
		country.setProvinceList(list);

		String xml = JaxbXmlUtil.beanToXml(country);
		System.out.println(xml);
	}

	@Test
	public void testXmlToBean() {
		String xml = "<?xml version='1.0' encoding='utf-8' ?>" 
				+ "<country>" 
				+ "<id>1</id>"
				+ "<createDate>2016-03-10 09:36:01</createDate>" 
				+ "<name>中国</name>" 
				+ "<provinces>" 
				+ "<province><name>广东省</name><provCity>广州市</provCity></province>" 
				+ "<province><name>湖南省</name><provCity>长沙市</provCity></province>" 
				+ "</provinces>" 
				+ "</country>";
		Country country = JaxbXmlUtil.xmlToBean(xml, Country.class);
		System.out.println(country.getId() + "--" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
				.format(country.getCreateDate()) + "--" + country.getName());
		for (Province p : country.getProvinceList()) {
			System.out.println(p.getName() + "---" + p.getProvCity());
		}
	}
}

 2.4、测试结果

 2.4.1、运行testBeanToXml方法

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<country>
    <id>1</id>
    <createDate>2016-03-10 05:24:57</createDate>
    <name>中国</name>
    <provinces>
        <province>
            <name>广东省</name>
            <provCity>广州市</provCity>
        </province>
        <province>
            <name>湖南省</name>
            <provCity>长沙市</provCity>
        </province>
    </provinces>
</country>

   2.4.2、运行testXmlToBean方法

1--2016-03-10 09:36:01--中国
广东省---广州市
湖南省---长沙市

 三、XStream实现Bean与xml互转

1、导入jar包

<dependency>
	<groupId>com.thoughtworks.xstream</groupId>
	<artifactId>xstream</artifactId>
	<version>1.4.8</version>
</dependency>

 2、重要注解说明

@XStreamAlias 定义别名

@XStreamAsAttribute 定义为属性

@XStreamOmitField  忽略

@XStreamConverter  处理日期格式

@XStreamImplicit(itemFieldName = "roles")  处理List

3、实例

3.1、定义JavaBean

import java.util.Date;
import java.util.List;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
import com.tzz.util.xml.DateConverter;

@XStreamAlias("user")
public class User {

	@XStreamAsAttribute
	private Integer id;
	private String name;
	@XStreamOmitField
	private int age;
	private String sex;
	@XStreamConverter(value = DateConverter.class)
	private Date birthday = new Date();
	@XStreamImplicit(itemFieldName = "roles")
	private List<Role> roles;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public List<Role> getRoles() {
		return roles;
	}

	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}import com.thoughtworks.xstream.annotations.XStreamAlias;

@XStreamAlias("role")
public class Role {

	private Integer id;
	private String name;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

 3.2、转换工具类

import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.dom4j.Element;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;

public class XStreamXmlUtil {

	/** XML转Bean对象 */
	@SuppressWarnings("unchecked")
	public static <T> T xmlToBean(String xml, Class<T> clazz) {
		XStream xstream = new XStream();
		xstream.registerConverter(new DateConverter());
		xstream.autodetectAnnotations(true);
		xstream.processAnnotations(clazz);
		xstream.setClassLoader(clazz.getClassLoader());
		return (T) xstream.fromXML(xml);
	}

	/** Bean对象转XML */
	public static String beanToXml(Object bean) {
//		return "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + new XStream().toXML(bean);
		XStream xstream = new XStream();
		xstream.registerConverter(new DateConverter());
		xstream.autodetectAnnotations(true);
		return xstream.toXML(bean);
	}
}

 3.3、测试类

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.junit.Test;

import com.tzz.test.util.xml.entity.Role;
import com.tzz.test.util.xml.entity.User;
import com.tzz.util.xml.XStreamXmlUtil;

public class TestXStreamXmlUtil {

	@Test
	public void testBeanToXml() {
		try {
			User user = new User();
			user.setId(1);
			user.setName("Test");
			user.setAge(20);
			user.setSex("1");
			user.setBirthday(new Date());
			Role role = new Role();
			role.setId(1);
			role.setName("角色1");
			Role role2 = new Role();
			role2.setId(2);
			role2.setName("角色2");
			List<Role> roles = new ArrayList<Role>();
			roles.add(role);
			roles.add(role2);
			user.setRoles(roles);
			String xml = XStreamXmlUtil.beanToXml(user);
			System.out.println(xml);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Test
	public void testXmlToBean() {
		String xml = 
		  "<user id='1'>"+
			  "<name>Test</name>"+
			  "<sex>1</sex>"+
			  "<birthday>2016-03-10 16:12:46</birthday>"+
			  "<roles>"+
			    "<id>1</id>"+
			    "<name>角色1</name>"+
			  "</roles>"+
			  "<roles>"+
			    "<id>2</id>"+
			    "<name>角色2</name>"+
			  "</roles>"+
		   "</user>";
		User user = XStreamXmlUtil.xmlToBean(xml, User.class);
		System.out.println(user.getId() + "--" + user.getName());
		List<Role> roles = user.getRoles();
		for (Role r : roles) {
			System.out.println(r.getName());
		}
	}
}

 3.4、测试结果

 3.4.1、运行testBeanToXml方法

<user id="1">
  <name>Test</name>
  <sex>1</sex>
  <birthday>2016-03-10 17:35:41</birthday>
  <roles>
    <id>1</id>
    <name>角色1</name>
  </roles>
  <roles>
    <id>2</id>
    <name>角色2</name>
  </roles>
</user>

  3.4.2、运行testXmlToBean方法

1--Test
角色1
角色2

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值