一.Jaxb處理java對象和xml之間轉換常用的annotation有:
- @XmlType
- @XmlElement
- @XmlRootElement
- @XmlAttribute
- @XmlAccessorType
- @XmlAccessorOrder
- @XmlTransient
- @XmlJavaTypeAdapter
二.常用annotation使用說明
- @XmlType
@XmlType用在class類的註解,常與@XmlRootElement,@XmlAccessorType一起使用。它有三個屬性:name、propOrder、namespace,經常使用的只有前兩個屬性。如:
@XmlType(name = "basicStruct", propOrder = { "intValue", "stringArray", "stringValue")
在使用@XmlType的propOrder 屬性時,必須列出JavaBean對象中的所有屬性,否則會報錯。
2.@XmlElement
@XmlElement將java對象的屬性對應為xml的節點,在使用@XmlElement時,可通過name屬性改變java對象屬性在xml中顯示的名稱。如:
@XmlElement(name="Address") private String yourAddress; 3.@XmlRootElement
@XmlRootElement用於類層級的註解,對應xml的跟元素,常與
@XmlType 和 @XmlAccessorType一起使用。如:
@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Address {} 4.@XmlAttribute @XmlAttribute用於把java對象的屬性對應為xml的屬性,並可通過name屬性為產生的xml屬性指定別名。如: @XmlAttribute(name="Country")
private String state; 5.@XmlAccessorType
@XmlAccessorType用於指定由java對象產生xml檔案時對java對象屬性的訪問方式。常與@XmlRootElement、@XmlType一起使用。它的屬性值是XmlAccessType的4個枚舉值,分 別為:
XmlAccessType.FIELD:java對象中的所有成員變數
XmlAccessType.PROPERTY:java對象中所有通過getter/setter方式訪問的成員變數
XmlAccessType.PUBLIC_MEMBER:java對象中所有的public存取權限的成員變數和通過getter/setter方式訪問的成員變數
XmlAccessType.NONE:java對象的所有屬性都不映射為xml的元素
注意:@XmlAccessorType的預設存取層級是XmlAccessType.PUBLIC_MEMBER,因此,如果java對象中的private成員變數設定了public許可權的getter/setter方法,就不要在 private變數上使用@XmlElement和@XmlAttribute註解,否則在由java對象產生xml時會報同一個屬性在java類裡存在兩次的錯誤。同理,如果@XmlAccessorType的存取權限 為XmlAccessType.NONE,如果在java的成員變數上使用了@XmlElement或@XmlAttribute註解,這些成員變數依然可以映射到xml檔案。
6.@XmlAccessorOrder
@XmlAccessorOrder用於對java對象產生的xml元素進行排序。它有兩個屬性值:
AccessorOrder.ALPHABETICAL:對產生的xml元素按字母書序排序
XmlAccessOrder.UNDEFINED:不排序
7.@XmlTransient
@XmlTransient用於標示在由java對象映射xml時,忽略此屬性。即,在產生的xml檔案中不出現此元素。
8.@XmlJavaTypeAdapter
@XmlJavaTypeAdapter常用在轉換比較複雜的對象時,如map類型或者格式化日期等。使用此註解時,需要自己寫一個adapter類繼承XmlAdapter抽象類別,並實現裡面的方法。
@XmlJavaTypeAdapter(value=xxx.class),value為自己定義的adapter類
XmlAdapter如下:
public abstract class XmlAdapter<ValueType,BoundType> { // Do-nothing constructor for the derived classes. protected XmlAdapter() {} // Convert a value type to a bound type. public abstract BoundType unmarshal(ValueType v); // Convert a bound type to a value type. public abstract ValueType marshal(BoundType v); } 三.樣本
1.Shop.java
package jaxb.shop;import java.util.Set;import javax.xml.bind.annotation.XmlAccessOrder;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;import javax.xml.bind.annotation.XmlType;import javax.xml.bind.annotation.XmlElementWrapper;import javax.xml.bind.annotation.XmlAccessorOrder;@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)@XmlAccessorType(XmlAccessType.FIELD)@XmlType(name = "shop", propOrder = { "name", "number", "describer", "address","orders" })
@XmlRootElement(name = "CHMart")public class Shop {@XmlAttributeprivate String name;// @XmlElementprivate String number;@XmlElementprivate String describer;@XmlElementWrapper(name = "orders")@XmlElement(name = "order")private Set<Order> orders;@XmlElementprivate Address address;public Shop() {}public Shop(String name, String number, String describer, Address address) {this.name = name;this.number = number;this.describer = describer;this.address = address;}getter/setter略
//同時使用了@XmlType(propOrder={})和@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL),但是產生的xml只按照propOrder定義的順序產生元素
2.Order.java
package jaxb.shop;import java.math.BigDecimal;import java.util.Date;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.XmlType;import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;@XmlType(name="order",propOrder={"shopName","orderNumber","price","amount","purDate","customer"})@XmlAccessorType(XmlAccessType.FIELD)@XmlRootElementpublic class Order {//@XmlElement private String shopName;@XmlAttributeprivate String orderNumber;//@XmlElement@XmlJavaTypeAdapter(value=DateAdapter.class)private Date purDate;//@XmlElementprivate BigDecimal price;//@XmlElementprivate int amount;//@XmlElementprivate Customer customer;public Order() {}public Order(String shopName, String orderNumber, Date purDate,BigDecimal price, int amount) {this.shopName = shopName;this.orderNumber = orderNumber;this.purDate = purDate;this.price = price;this.amount = amount;}
getter/setter略
//@XmlAccessorType(XmlAccessType.FIELD),所以此處注釋掉了@XmlElement,xml中依然會產生這些元素
3.Customer.java
package jaxb.shop;import java.util.Set;import javax.xml.bind.annotation.XmlType;import javax.xml.bind.annotation.XmlAttribute;import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlRootElement;import javax.xml.bind.annotation.XmlAccessType;import javax.xml.bind.annotation.XmlAccessorType;@XmlType@XmlAccessorType(XmlAccessType.FIELD)@XmlRootElementpublic class Customer {@XmlAttributeprivate String name;private String gender;private String phoneNo;private Address address;private Set<Order> orders;public Customer() {}public Customer(String name, String gender, String phoneNo, Address address) {this.name = name;this.gender = gender;this.phoneNo = phoneNo;this.address = address;}
getter/setter略
4.Address.java
package jaxb.shop;import javax.xml.bind.annotation.XmlAttribute;import javax.xml.bind.annotation.XmlType;import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlRootElement;import javax.xml.bind.annotation.XmlAccessType;import javax.xml.bind.annotation.XmlAccessorType;import javax.xml.bind.annotation.XmlAccessOrder;import javax.xml.bind.annotation.XmlAccessorOrder;@XmlType(propOrder={"state","province","city","street","zip"})@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)@XmlAccessorType(XmlAccessType.NONE)@XmlRootElementpublic class Address {@XmlAttribute private String state;@XmlElementprivate String province;@XmlElementprivate String city;@XmlElementprivate String street;@XmlElementprivate String zip;public Address() {super();}public Address(String state, String province, String city, String street,String zip) {super();this.state = state;this.province = province;this.city = city;this.street = street;this.zip = zip;}
getter/setter略
//注意:雖然@XmlAccessorType為XmlAccessType.NONE,但是在java類的私人屬性上加了@XmlAttribute和@XmlElement註解後,這些私人成員會映射產生xml的元素
5.DateAdapter.java
package jaxb.shop;import java.util.Date;import java.text.SimpleDateFormat;import javax.xml.bind.annotation.adapters.XmlAdapter;public class DateAdapter extends XmlAdapter<String, Date> {private String pattern = "yyyy-MM-dd HH:mm:ss";SimpleDateFormat fmt = new SimpleDateFormat(pattern);@Overridepublic Date unmarshal(String dateStr) throws Exception {return fmt.parse(dateStr);}@Overridepublic String marshal(Date date) throws Exception {return fmt.format(date);}}
//用于格式化日期在xml中的顯示格式,並且由xml unmarshal為java對象時,將字串解析為Date對象
6.ShopTest.java
package jaxb.shop;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.math.BigDecimal;import java.util.Date;import java.util.HashSet;import java.util.Set;import javax.xml.bind.JAXBContext;import javax.xml.bind.JAXBException;import javax.xml.bind.Marshaller;import javax.xml.bind.Unmarshaller;public class ShopTest {public static void main(String[] args) throws JAXBException, IOException{Set<Order> orders = new HashSet<Order>();Address address1 = new Address("China", "ShangHai", "ShangHai", "Huang", "200000");Customer customer1 = new Customer("Jim", "male", "13699990000", address1);Order order1 = new Order("Mart", "LH59900", new Date(), new BigDecimal(60), 1);order1.setCustomer(customer1);Address address2 = new Address("China", "JiangSu", "NanJing", "ZhongYangLu", "210000");Customer customer2 = new Customer("David", "male", "13699991000", address2);Order order2 = new Order("Mart", "LH59800", new Date(), new BigDecimal(80), 1);order2.setCustomer(customer2);orders.add(order1);orders.add(order2);Address address3 = new Address("China", "ZheJiang", "HangZhou", "XiHuRoad", "310000");Shop shop = new Shop("CHMart", "100000", "EveryThing",address3);shop.setOrder(orders);FileWriter writer = null;JAXBContext context = JAXBContext.newInstance(Shop.class);try {Marshaller marshal = context.createMarshaller();marshal.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);marshal.marshal(shop, System.out);writer = new FileWriter("shop.xml");marshal.marshal(shop, writer);} catch (Exception e) {e.printStackTrace();}Unmarshaller unmarshal = context.createUnmarshaller();FileReader reader = new FileReader("shop.xml") ;Shop shop1 = (Shop)unmarshal.unmarshal(reader);Set<Order> orders1 = shop1.getOrder();for(Order order : orders1){System.out.println("***************************");System.out.println(order.getOrderNumber());System.out.println(order.getCustomer().getName());System.out.println("***************************");}}}
7.產生的xml檔案
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CHMart name="CHMart"> <number>100000</number> <describer>EveryThing</describer> <address state="China"> <province>ZheJiang</province> <city>HangZhou</city> <street>XiHuRoad</street> <zip>310000</zip> </address> <orders> <order orderNumber="LH59800"> <shopName>Mart</shopName> <price>80</price> <amount>1</amount> <purDate>2012-03-25 12:57:23</purDate> <customer name="David"> <gender>male</gender> <phoneNo>13699991000</phoneNo> <address state="China"> <province>JiangSu</province> <city>NanJing</city> <street>ZhongYangLu</street> <zip>210000</zip> </address> </customer> </order> <order orderNumber="LH59900"> <shopName>Mart</shopName> <price>60</price> <amount>1</amount> <purDate>2012-03-25 12:57:23</purDate> <customer name="Jim"> <gender>male</gender> <phoneNo>13699990000</phoneNo> <address state="China"> <province>ShangHai</province> <city>ShangHai</city> <street>Huang</street> <zip>200000</zip> </address> </customer> </order> </orders></CHMart>
以上是以一個簡單的商店訂單模型作為樣本。