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... }
JAXB工具類: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... }
測試用例: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設定別名沒有作用。