XML學習筆記(六):Jaxb負責xml與javaBean對映
前言:
1、兩套標準:Jax-ws(web service)和 Jax-rs(restful)。
2、在JAVA EE 5\6中,jaxb可以很方便的與jax-rs、jax-ws整合,極大的簡化了web service介面的開發工作量。jaxb負責xml與javaBean的對映。
3、cxf等架構的使用,ws中不需要手動寫對映,而restfu則需要手動書寫註解。(也可以使用JAXB的XJC工具,通過定義schema的方式實現Java物件與XML的繫結)。
4、jaxb除了在ws與restful中廣泛使用,也可以作為解析xml的一種日常技術。
一、web service中的jaxb
1、在使用cxf的客戶端時,一般使用 wsdl2java 命令生成,所以不需要自己寫jaxb的程式碼。如:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "cat", propOrder = {
"color",
"id",
"name"
})
public class Cat {
protected String color;
protected Integer id;
protected String name;
//......
}
2、其實這邊對映的就是 soap訊息,與訪問的 wsdl 具有一致性。
二、jaxb詳解。
(一)例項
1、javaBean例項:
package cn.rest.bean; import java.util.List; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; /** * * UserBean.java * * @title User的傳輸資料類 * @description * @author SAM-SHO * @Date 2014-11-25 */ @XmlRootElement(name = "USER") //@XmlAccessorType(XmlAccessType.FIELD ) //寫這個註解,就不需要@XmlElement註解,一般和XmlType一起使用,指定名稱。 //@XmlType(propOrder = { "name", "age" ,"userAddress","phoneList"}) public class UserBean { private String name; private String key; private String age; private UserAddress userAddress;//地址 private List<UserPhone> phoneList ;//手機 @XmlElement(name="NAME") public String getName() { return name; } public void setName(String name) { this.name = name; } @XmlElement(name = "AGE") public String getAge() { return age; } public void setAge(String age) { this.age = age; } @XmlElement(name = "UserAddress") public UserAddress getUserAddress() { return userAddress; } public void setUserAddress(UserAddress userAddress) { this.userAddress = userAddress; } @XmlElementWrapper(name = "PhoneList")//標註集合 @XmlElement(name = "UserPhone") public List<UserPhone> getPhoneList() { return phoneList; } public void setPhoneList(List<UserPhone> phoneList) { this.phoneList = phoneList; } @XmlAttribute(name="key")//屬性 public String getKey() { return key; } public void setKey(String key) { this.key = key; } }
package cn.rest.bean; public class UserPhone { private String type;//電話號碼型別 private String num;//電話號碼 public String getType() { return type; } public void setType(String type) { this.type = type; } public String getNum() { return num; } public void setNum(String num) { this.num = num; } }
package cn.rest.bean;
import javax.xml.bind.annotation.XmlElement;
public class UserAddress {
private String homeAddress;//家庭地址
private String workAddress;//公司地址
@XmlElement(name = "HomeAddress")
public String getHomeAddress() {
return homeAddress;
}
public void setHomeAddress(String homeAddress) {
this.homeAddress = homeAddress;
}
@XmlElement(name = "WorkAddress")
public String getWorkAddress() {
return workAddress;
}
public void setWorkAddress(String workAddress) {
this.workAddress = workAddress;
}
}
2、解析工具。
1)javaBean 對映成 xml,使用 Marshaller 。
/**
* Objext 轉成 XML
*
* @param object
*/
public static void Object2Xml(Object object) {
// FileWriter writer = null;
try {
JAXBContext context = JAXBContext.newInstance(object.getClass());
Marshaller marshal = context.createMarshaller();
marshal.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // 格式化輸出
marshal.setProperty(Marshaller.JAXB_ENCODING, "utf-8");// 編碼格式,預設為utf-8
marshal.setProperty(Marshaller.JAXB_FRAGMENT, false);// 是否省略xml頭資訊
marshal.marshal(object, System.out);
// writer = new FileWriter("shop.xml");
// marshal.marshal(object, writer);
} catch (Exception e) {
e.printStackTrace();
}
}
2)xml 對映成 javaBean,使用 Unmarshaller 。
/**
* xml 轉成特定的Bean
*
* @param xml
* @return
*/
public static UserBean parseXml2UserBean(String xml) {
try {
JAXBContext context = JAXBContext.newInstance(UserBean.class);
InputSource is = new InputSource();
StringReader xmlStr = new StringReader(xml);
is.setCharacterStream(xmlStr);
Unmarshaller unmarshaller = context.createUnmarshaller();
UserBean user = (UserBean) unmarshaller.unmarshal(is);
return user;
} catch (JAXBException e) {
e.printStackTrace();
return null;
}
}
3)測試:
UserBean tUserBean = new UserBean();
tUserBean.setName("SAM-SHO");
tUserBean.setAge("27");
tUserBean.setKey("屬性111");
UserAddress tUserAddress = new UserAddress();
tUserAddress.setWorkAddress("蘇州園區");
tUserAddress.setHomeAddress("蘇州高新區");
tUserBean.setUserAddress(tUserAddress);
List<UserPhone> phoneList = new ArrayList<UserPhone>();
UserPhone tUserPhone = new UserPhone();
tUserPhone.setType("移動");
tUserPhone.setNum("13612345678");
phoneList.add(tUserPhone);
tUserPhone = new UserPhone();
tUserPhone.setType("聯通");
tUserPhone.setNum("13798765432");
phoneList.add(tUserPhone);
tUserBean.setPhoneList(phoneList);
ObjectAndXmlHandle.Object2Xml(tUserBean);
【輸出】
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<USER key="屬性111">
<AGE>27</AGE>
<NAME>SAM-SHO</NAME>
<PhoneList>
<UserPhone>
<num>13612345678</num>
<type>移動</type>
</UserPhone>
<UserPhone>
<num>13798765432</num>
<type>聯通</type>
</UserPhone>
</PhoneList>
<UserAddress>
<HomeAddress>蘇州高新區</HomeAddress>
<WorkAddress>蘇州園區</WorkAddress>
</UserAddress>
</USER>
(二)jaxb 註解詳解:
1、@XmlRootElement 將一個Java類對映為一段XML的根節點。引數:
name 定義這個根節點的名稱
namespace 定義這個根節點名稱空間
2、@XmlAccessorType 定義對映這個類中的何種型別需要對映到XML。可接收四個引數,分別是:
XmlAccessType.FIELD:對映這個類中的所有欄位到XML
XmlAccessType.PROPERTY:對映這個類中的屬性(get/set方法)到XML
XmlAccessType.PUBLIC_MEMBER:將這個類中的所有public的field或property同時對映到XML(預設)
XmlAccessType.NONE:不對映
3、@XmlElement 指定一個欄位或get/set方法對映到XML的節點。如,當一個類的XmlAccessorType 被標註為
PROPERTY時,在某一個沒有get/set方法的欄位上標註此註解,即可將該欄位對映到XML。引數:
defaultValue 指定節點預設值
name 指定節點名稱
namespace 指定節點名稱空間
required 是否必須(預設為false)
nillable 該欄位是否包含 nillable="true" 屬性(預設為false)
type 定義該欄位或屬性的關聯型別
4、@XmlAttribute 指定一個欄位或get/set方法對映到XML的屬性。引數:
name 指定屬性名稱
namespace 指定屬性名稱空間
required 是否必須(預設為false)
5、@XmlTransient 定義某一欄位或屬性不需要被對映為XML。如,當一個類的XmlAccessorType 被標註為PROPERTY時,在某一get/set方法的欄位上標註此註解,那麼該屬性則不會被對映。
6、@XmlType 定義對映的一些相關規則。引數:
propOrder 指定對映XML時的節點順序
actoryClass 指定UnMarshal時生成對映類例項所需的工廠類,預設為這個類本身
factoryMethod 指定工廠類的工廠方法
name 定義XML Schema中type的名稱
7、@XmlElementWrapper 為陣列元素或集合元素定義一個父節點。如,類中有一元素為List items,若不加此註解,該元素將被對映為namespace 指定Schema中的名稱空間
<items>...</items>
<items>...</items>
這種形式,此註解可將這個元素進行包裝,如:
@XmlElementWrapper(name="items")
@XmlElement(name="item")
public List items;
將會生成這樣的XML樣式:
<items>
<item>...</item>
<item>...</item>
</items>
8、@XmlJavaTypeAdapter 自定義某一欄位或屬性對映到XML的介面卡。如,類中包含一個介面,我們可以定義一個介面卡(繼承自 javax.xml.bind.annotation.adapters.XmlAdapter類),指定這個介面如何對映到XML。
9、@XmlSchema 配置整個包的namespace,這個註解需放在package-info.java檔案中。