本文主要總結JAXB基本使用方法和注意事項!java
經過下文的XML示例內容進行JAXB的簡單實踐 ide
<?xml version="1.0" encoding="UTF-8"?> <Provinces> <Province id="B001"> <name>北京</name> <code>30000</code> </Province> <Province id="Z001"> <name>浙江</name> <code>60000</code> </Province> <Province id="J001"> <name>江蘇</name> <code>90000</code> <city citycode="90001">南京市</city> <city citycode="90002">鹽城市</city> <city citycode="90003">揚州市</city> <city citycode="90004">南通市</city> </Province> </Provinces>
1、分析citys.xml,能夠定義三個示例類ProvincesBean,ProvinceBean,CityBean.java工具
package my.jaxb.bean; 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.XmlRootElement; /** <Provinces> <Province id="B001">... <Province id="B002">... <Province id="J001">... </Provinces> **/ @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "Provinces") public class ProvincesBean { @XmlElement(name = "Province") private List<ProvinceBean> provinces = null; public List<ProvinceBean> getProvinces() { return provinces; } public void setProvinces(List<ProvinceBean> provinces) { this.provinces = provinces; } public String toString() { return "ProvincesBean ( provinces = " + this.provinces + " )"; } }
package my.jaxb.bean; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; /** <Province id="J001"> <name>江蘇</name> <code>90000</code> <city citycode="90001">南京市</city> <city citycode="90002">鹽城市</city> <city citycode="90003">揚州市</city> <city citycode="90004">南通市</city> </Province> **/ @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "Province") public class ProvinceBean { @XmlAttribute private String id = ""; private String name = ""; private String code = ""; @XmlElement(name = "city") private List<CityBean> citys = null; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<CityBean> getCitys() { return citys; } public void setCitys(List<CityBean> citys) { this.citys = citys; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String toString() { return "ProvinceBean ( id = " + this.id + " name = " + this.name + " code = " + this.code + " citys = " + this.citys + " )"; } }
package my.jaxb.bean; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlValue; /** <city citycode="90001">南京市</city> **/ @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "city") public class CityBean { public CityBean() { } public CityBean(String cityCode, String value) { super(); this.cityCode = cityCode; this.value = value; } @XmlAttribute(name = "citycode") private String cityCode = ""; @XmlValue private String value = ""; public String getCityCode() { return cityCode; } public void setCityCode(String cityCode) { this.cityCode = cityCode; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public String toString() { return "CityBean ( cityCode = " + this.cityCode + " value = " + this.value + " )"; } }
2、編寫序列化和反序列化的工具類-XmlUtils 測試
package my.jaxb.comm; import java.io.File; 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; public class XmlUtils { // JavaBean to XML public static String toXML(Object obj) { try { JAXBContext context = JAXBContext.newInstance(obj.getClass()); Marshaller marshaller = context.createMarshaller(); // 設置編碼格式 marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); // 是否格式化生成的XML marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // 是否省略XML頭聲明信息 marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false); StringWriter writer = new StringWriter(); marshaller.marshal(obj, writer); return writer.toString(); } catch (JAXBException e) { throw new RuntimeException(e.getMessage()); } } // XML to JavaBean public static <MY> MY fromXML(String xml, Class<MY> declareType) { try { JAXBContext context = JAXBContext.newInstance(declareType); Unmarshaller unmarshaller = context.createUnmarshaller(); Object obj = unmarshaller.unmarshal(new StringReader(xml)); return (MY) obj; } catch (JAXBException e) { throw new RuntimeException(e.getMessage()); } } // XML(path) to JavaBean public static <MY> MY fromXMLPath(String xmlPath, Class<MY> declareType) { try { JAXBContext context = JAXBContext.newInstance(declareType); Unmarshaller unmarshaller = context.createUnmarshaller(); Object obj = unmarshaller.unmarshal(new File(xmlPath)); return (MY) obj; } catch (JAXBException e) { throw new RuntimeException(e.getMessage()); } } }
3、編寫測試代碼,內部實現了JavaBean to XML和XML to JavaBean兩個操做this
package my.jaxb.test; import java.util.ArrayList; import java.util.List; import my.jaxb.bean.CityBean; import my.jaxb.bean.ProvinceBean; import my.jaxb.bean.ProvincesBean; import my.jaxb.comm.XmlUtils; public class ToXMLFoo { public static void main(String[] args) { ProvincesBean provinces = new ProvincesBean(); provinces.setProvinces(getProvinces()); // JavaBean to XML String xml = XmlUtils.toXML(provinces); System.out.println(xml); System.out.println("------------------------------"); // XML to JavaBean provinces = XmlUtils.fromXML(xml, ProvincesBean.class); System.out.println(provinces); } private static List<ProvinceBean> getProvinces() { List<ProvinceBean> provList = new ArrayList<ProvinceBean>(); ProvinceBean prov = new ProvinceBean(); prov.setId("B001"); prov.setName("北京"); prov.setCode("30000"); ProvinceBean prov2 = new ProvinceBean(); prov2.setId("Z001"); prov2.setName("浙江"); prov2.setCode("60000"); ProvinceBean prov3 = new ProvinceBean(); prov3.setId("J001"); prov3.setName("江蘇"); prov3.setCode("90000"); // 單獨增長城市 prov3.setCitys(getCitys()); provList.add(prov); provList.add(prov2); provList.add(prov3); return provList; } private static List<CityBean> getCitys() { List<CityBean> cityList = new ArrayList<CityBean>(); CityBean city = new CityBean("90001", "南京市"); CityBean city2 = new CityBean("90002", "鹽城市"); CityBean city3 = new CityBean("90003", "揚州市"); CityBean city4 = new CityBean("90004", "南通市"); cityList.add(city); cityList.add(city2); cityList.add(city3); cityList.add(city4); return cityList; } }
4、測試輸出結果 編碼
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Provinces> <Province id="B001"> <name>北京</name> <code>30000</code> </Province> <Province id="Z001"> <name>浙江</name> <code>60000</code> </Province> <Province id="J001"> <name>江蘇</name> <code>90000</code> <city citycode="90001">南京市</city> <city citycode="90002">鹽城市</city> <city citycode="90003">揚州市</city> <city citycode="90004">南通市</city> </Province> </Provinces> ------------------------------ ProvincesBean ( provinces = [ProvinceBean ( id = B001 name = 北京 code = 30000 citys = null ), ProvinceBean ( id = Z001 name = 浙江 code = 60000 citys = null ), ProvinceBean ( id = J001 name = 江蘇 code = 90000 citys = [CityBean ( cityCode = 90001 value = 南京市 ), CityBean ( cityCode = 90002 value = 鹽城市 ), CityBean ( cityCode = 90003 value = 揚州市 ), CityBean ( cityCode = 90004 value = 南通市 )] )] )
1、直接編寫測試代碼,內部實現了XML to JavaBean的操做 spa
package my.jaxb.test; import my.jaxb.bean.ProvincesBean; import my.jaxb.comm.XmlUtils; public class FromXMLFoo { public static void main(String[] args) { String xmlPath = FromXMLFoo.class.getResource("/").getPath() + "citys.xml"; // XML(path) to JavaBean ProvincesBean bean = XmlUtils.fromXMLPath(xmlPath, ProvincesBean.class); System.out.println(bean); } }
2、測試輸出結果3d
ProvincesBean ( provinces = [ProvinceBean ( id = B001 name = 北京 code = 30000 citys = null ), ProvinceBean ( id = Z001 name = 浙江 code = 60000 citys = null ), ProvinceBean ( id = J001 name = 江蘇 code = 90000 citys = [CityBean ( cityCode = 90001 value = 南京市 ), CityBean ( cityCode = 90002 value = 鹽城市 ), CityBean ( cityCode = 90003 value = 揚州市 ), CityBean ( cityCode = 90004 value = 南通市 )] )] )
一、要序列化的類加上@XmlRootElement註解,不然會報錯!code
二、JAXB序列化XML時 默認序列化getter和setter,且getter和setter必須成對出現纔會被序列化。
三、屬性名稱,默認序列化出來的類和屬性名稱默認是首字母轉換爲小寫,若須要控制屬性名稱須要在getter或setter上
使用 @XmlElement(name = "Province") 指定名稱,此處要注意的是@XmlElement也能夠放置在getter或setter上都行,
但只能放一個,也就是說不能同時在getter和setter或field字段三者中間任意兩者上同時使用 @XmlElement註解!
四、如控制根節點名稱?
Re: 使用@XmlRootElement指定name屬性便可,如@XmlRootElement(name = "Provinces")。xml
五、怎麼添加命名空間
Re: 使用@XmlRootElement(namespace="my.jaxb") 指定namespace屬性,此處不作代碼示例。
六、怎麼精確控制每一個屬性名稱
Re: JAXB自動轉化爲首字母小寫會致使不可預料的屬性名稱出現,不嫌麻煩的話爲每一個屬性設置@XmlElement(name=""),想省事的話使用Field字段名稱便可。
七、怎麼樣實現序列化時使用Field字段而不是使用setter和getter
Re: 在要使用的類上面加上@XmlAccessorType(XmlAccessType.FIELD)註解,並指定爲XmlAccessType.FIELD,
這裏強烈推薦使用@XmlAccessorType(XmlAccessType.FIELD)註解,由於這樣你能夠精確的控制每一個元素的名稱,
而不須要爲每一個屬性去設置@XmlElement(name="")註解,固然也能夠在Field上使用@XmlElement註解。
八、一個元素既有屬性也有文本內容狀況如何配置?
Re: 如:<city citycode="90001">南京市</city> ,此時citycode字段經過@XmlAttribute(name = "citycode")控制,value字段經過@XmlValue控制便可。