JAXB轻松转换xml对象和java对象
实体类如下:
package com.cn.entity; 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; @XmlRootElement(name = "person") @XmlAccessorType(XmlAccessType.NONE) public class Person { //姓名 @XmlElement(name = "newName") private String name; //性别 @XmlElement(name = "sex_1") private String sex; //年龄 @XmlElement private int age; //地址 @XmlElementWrapper(name = "Address") @XmlElement(name = "address") private List<Address> Address; get... set... }
package com.cn.entity; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.PROPERTY) @XmlType(propOrder={"country","province","city","county","town"}) public class Address { //国 //@XmlElement(name = "country000") private String country; //省 //@XmlElement private String province; //市 //@XmlElement private String city; //县 //@XmlElement private String county; //镇 //@XmlElement(required = true) private String town; get... set... }
JAXB工具类:
package com.cn.util; 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; import org.apache.log4j.Logger; /** * JAXB工具类 * @author sun.kai * 2016年8月18日 */ public class JaxbUtil { private static Logger logger = Logger.getLogger(JaxbUtil.class); private static JAXBContext jaxbContext; //xml转java对象 @SuppressWarnings("unchecked") public static <T> T xmlToBean(String xml,Class<T> c){ T t = null; try { jaxbContext = JAXBContext.newInstance(c); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); t = (T) unmarshaller.unmarshal(new StringReader(xml)); } catch (JAXBException e) { logger.info(e.getMessage()); } return t; } //java对象转xml public static String beanToXml(Object obj){ StringWriter writer = null; try { jaxbContext=JAXBContext.newInstance(obj.getClass()); Marshaller marshaller = jaxbContext.createMarshaller(); //Marshaller.JAXB_FRAGMENT:是否省略xml头信息,true省略,false不省略 marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); //Marshaller.JAXB_FORMATTED_OUTPUT:决定是否在转换成xml时同时进行格式化(即按标签自动换行,否则即是一行的xml) marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); //Marshaller.JAXB_ENCODING:xml的编码方式 marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); writer = new StringWriter(); marshaller.marshal(obj, writer); } catch (JAXBException e) { logger.info(e.getMessage()); } return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + writer.toString(); } }
测试用例:
package com.test.test; import java.util.ArrayList; import java.util.List; import com.cn.entity.Address; import com.cn.entity.Person; import com.cn.util.JaxbUtil; public class TestJaxb { public static void main(String[] args) { long time1 = System.currentTimeMillis(); //测试java对象转xml,java对象中包含集合对象 Person person = new Person(); person.setName("admin管理员"); person.setSex("男"); person.setAge(25); List<Address> adds = new ArrayList<Address>(); Address address1 = new Address(); address1.setCountry("中国"); address1.setProvince("安徽"); address1.setCity("宿州"); address1.setCounty("萧县"); Address address2 = new Address(); address2.setCountry("中国"); address2.setProvince("上海"); address2.setCity(null); address2.setCounty(""); adds.add(address1); adds.add(address2); person.setAddress(adds); String xml = JaxbUtil.beanToXml(person); System.out.println(xml); //测试xml转java对象 Person person2 = JaxbUtil.xmlToBean(xml,Person.class); System.out.println(person2.getAddress().get(0).getCountry()); System.out.println(person2.getAddress().get(1).getProvince()); long time2 = System.currentTimeMillis(); System.out.println((time2-time1)+"ms"); } }
执行后控制台打印:
<?xml version="1.0" encoding="UTF-8"?> <person> <newName>admin管理员</newName> <sex_1>男</sex_1> <age>25</age> <Address> <address> <country>中国</country> <province>安徽</province> <city>宿州</city> <county>萧县</county> </address> <address> <country>中国</country> <province>上海</province> <county></county> </address> </Address> </person> 中国 上海 531ms
总结:
(1) @XmlRootElement:根节点,且可以增加属性(name="NewRootElementName"),那么生成的xml串的标签别名是NewRootElementName。
(2) @XmlAttribute:该属性作为xml的属性,且可以增加属性(name="NewAttributeName"),那么生成的xml串的标签别名是NewAttributeName。
(3) @XmlElement:该属性作为xml的元素,且可以增加属性(name="NewElementName"),那么生成的xml串的标签别名是NewElementName。
(4) @XmlElementWrapper:对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的XML元素(称为包装器。如果不加该注解,集合中的每个对象的父节点不是List了,而是Class。
(5) @XmlType,将Java类或枚举类型映射到XML模式类型。
(6) @XmlAccessorType(XmlAccessType.FIELD) ,控制字段或属性的序列化。
XmlAccessType.FIELD表示JAXB将自动绑定Java类中的每个非静态的(static)、非瞬态的(由@XmlTransient标 注)字段到XML,即使在java对象中的属性上不加注解@XmlElement等也可以转成XML对象。
XmlAccessType.NONE表示JAXB不自动绑定属性字段到XML,所以需要在需要转换的属性上加上注解@XmlElement才能转成XML对象。
XmlAccessType.PROPERTY表示只有属性(有get/set方法)才能被转换成XML中的标签,并且属性上不许有注解@XmlElement等,除非用@XmlTransient注释。
XmlAccessType.PUBLIC_MEMBER表示每个公共(public)获取(get)方法/设置(set)方法对和每个公共字段将会自动绑定到 XML,除非由@XmlTransient注释。
(7) @XmlAccessorOrder,控制JAXB 绑定类中属性和字段的排序。
(8) @XmlJavaTypeAdapter,使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML
(9) 对于根节点中的对象,在该对象类上用@XmlRootElement设置别名没有作用。