JAXB(Java Architecture for XML Binding) 是一個業界的標准,是一項可以根據XML Schema產生Java類的技術。該過程中,JAXB也提供了將XML實例文檔反向生成Java對象樹的方法,並能將Java對象樹的內容重新寫到XML實例文檔。從另一方面來講,JAXB提供了快速而簡便的方法將XML模式綁定到Java表示,從而使得Java開發者在Java應用程序中能方便地結合XML數據和處理函數。
好了,廢話少說,看看簡單的例子。
介紹下相關的類。SmsDeliverReq是一個請求對象,類中有兩個屬性,分別為ReqHeader reqHeader和List<SmsBody> smsBodys。ReqHeader和SmsBody都為自定義類型。這兩個類中的屬性都為基本數據類型。
現在需要做的是將SmsDeliverReq的實例轉換為xml和將xml轉換為SmsDeliverReq實例,Test.java中封裝了xml->javabean 和 javabean->xml的兩個方法。並且實現了將生成的xml格式的字符串保存到xml文件中
ReqHeader.java
package cn.mr.javabeanxml; import javax.xml.bind.annotation.XmlElement; /** * 請求頭對象 * @author xuejiangtao * Jul 25, 2013 9:33:57 PM */ public class ReqHeader { /** * 系統編號 */ private String sysId; /** * 鑒權碼 */ private String authCode; /** * 流水號 */ private String reqNo; public String getSysId() { return sysId; } @XmlElement(name="SYSID") public void setSysId(String sysId) { this.sysId = sysId; } public String getAuthCode() { return authCode; } @XmlElement(name="AUTHCODE") public void setAuthCode(String authCode) { this.authCode = authCode; } public String getReqNo() { return reqNo; } @XmlElement(name="REQNO") public void setReqNo(String reqNo) { this.reqNo = reqNo; } }
SmsBody.java
package cn.mr.javabeanxml; import javax.xml.bind.annotation.XmlElement; /** * 請求內容 * @author xuejiangtao * Jul 25, 2013 9:34:16 PM */ public class SmsBody { /** * 短信內容 */ private String content; /** * 手機號 */ private String sourceAddr; /** * 服務代碼 */ private String destAddr; public String getContent() { return content; } @XmlElement(name="CONTENT") public void setContent(String content) { this.content = content; } public String getSourceAddr() { return sourceAddr; } @XmlElement(name="SOURCEADDR") public void setSourceAddr(String sourceAddr) { this.sourceAddr = sourceAddr; } public String getDestAddr() { return destAddr; } @XmlElement(name="DESTADDR") public void setDestAddr(String destAddr) { this.destAddr = destAddr; } }
SmsDeliverReq.java
package cn.mr.javabeanxml; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; /** * 請求對象 * @author xuejiangtao * Jul 25, 2013 9:34:26 PM */ @XmlRootElement(name="SMSDELIVERREQ") public class SmsDeliverReq { private ReqHeader reqHeader; private List<SmsBody> smsBodys; @XmlElement(name="REQHEADER") public ReqHeader getReqHeader() { return reqHeader; } public void setReqHeader(ReqHeader reqHeader) { this.reqHeader = reqHeader; } @XmlElementWrapper(name="SMSBODYS") @XmlElement(name="SMSBODY") public List<SmsBody> getSmsBodys() { return smsBodys; } public void setSmsBodys(List<SmsBody> smsBodys) { this.smsBodys = smsBodys; } }
Test.java
package cn.mr.javabeanxml; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.StringReader; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import cn.mr.javabeanxml.ReqHeader; import cn.mr.javabeanxml.SmsBody; import cn.mr.javabeanxml.SmsDeliverReq; public class Test { /** * XML轉換為javabean * Jul 25, 2013 9:39:05 PM xuejiangtao添加此方法 * @param <T> * @param xml * @param t * @return * @throws JAXBException */ public static <T> T xmlToBean(String xml, T t) throws JAXBException { JAXBContext context = JAXBContext.newInstance(t.getClass()); Unmarshaller um = context.createUnmarshaller(); StringReader sr = new StringReader(xml); t = (T) um.unmarshal(sr); return t; } /** * javabean轉換為XML * Jul 25, 2013 9:39:09 PM xuejiangtao添加此方法 * @param smsDeliverReq * @return * @throws JAXBException * @throws FileNotFoundException */ public static <T> StringWriter beanToXml(T t) throws JAXBException, FileNotFoundException { JAXBContext context = JAXBContext.newInstance(t.getClass()); Marshaller m = context.createMarshaller(); StringWriter sw = new StringWriter(); m.marshal(t, sw); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);//是否格式化 m.marshal(t, new FileOutputStream("src/cn/mr/javabeanxml/test.xml")); return sw; } /** * Jul 24, 2013 10:12:39 PM xuejiangtao添加此方法 * @param args * @throws JAXBException * @throws FileNotFoundException */ public static void main(String[] args) throws JAXBException, FileNotFoundException { ReqHeader reqHeader = new ReqHeader(); reqHeader.setReqNo("111"); reqHeader.setAuthCode("DDDD"); reqHeader.setSysId("jjj"); SmsBody smsBody = new SmsBody(); smsBody.setContent("類容訥訥"); smsBody.setDestAddr("1589594"); smsBody.setSourceAddr("9999"); SmsBody smsBody1 = new SmsBody(); smsBody1.setContent("asdf"); smsBody1.setDestAddr("asdf"); smsBody1.setSourceAddr("4fdf"); SmsDeliverReq smsDeliverReq = new SmsDeliverReq(); smsDeliverReq.setReqHeader(reqHeader); List<SmsBody> smsBodys = new ArrayList<SmsBody>(); smsBodys.add(smsBody); smsBodys.add(smsBody1); smsDeliverReq.setSmsBodys(smsBodys); StringWriter sw = beanToXml(smsDeliverReq); System.out.println(sw.toString()); SmsDeliverReq xmlToBean = xmlToBean(sw.toString(), smsDeliverReq); System.out.println(xmlToBean.toString()); } }
一下內容來自百度百科,個人覺得非常重要。
JDK中JAXB相關的重要Class和Interface:
JAXBContext類,是應用的入口,用於管理XML/Java綁定信息。
Marshaller接口,將Java對象序列化為XML數據。
Unmarshaller接口,將XML數據反序列化為Java對象。
JDK中JAXB相關的重要Annotation:
@XmlType,將Java類或枚舉類型映射到XML模式類型
@XmlAccessorType(XmlAccessType.FIELD) ,控制字段或屬性的序列化。FIELD表示JAXB將自動綁定Java類中的每個非靜態的(static)、非瞬態的(由@XmlTransient標注)字段到XML。其他值還有XmlAccessType.PROPERTY和XmlAccessType.NONE。
@XmlAccessorOrder,控制JAXB 綁定類中屬性和字段的排序。
@XmlJavaTypeAdapter,使用定制的適配器(即擴展抽象類XmlAdapter並覆蓋marshal()和unmarshal()方法),以序列化Java類為XML。
@XmlElementWrapper ,對於數組或集合(即包含多個元素的成員變量),生成一個包裝該數組或集合的XML元素(稱為包裝器)。
@XmlRootElement,將Java類或枚舉類型映射到XML元素。
@XmlElement,將Java類的一個屬性映射到與屬性同名的一個XML元素。
@XmlAttribute,將Java類的一個屬性映射到與屬性同名的一個XML屬性。
其他:
對於要序列化(marshal)為XML的Java類,絕不能把成員變量聲明為public,否則運行將拋出異常com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException。
對於JAXB相關的重要Annotation的聲明,如@Xml.....,可以放在成員變量的setter()或getter()方法上,兩者中任選其一即可,但決不能放在成員變量上,否則運行將拋出異常com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException。