1. 程式人生 > >JAXB輕鬆轉換xml物件和java物件

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設定別名沒有作用。