[CXF REST标准实战系列] 一、JAXB xml与javaBean的转换(转)
轉自:[CXF REST標準實戰系列] 一、JAXB xml與javaBean的轉換
?
文章Points:
1、不認識到犯錯,然后得到永久的教訓。
2、認識JAXB
3、代碼實戰
?
?
1、不認識到犯錯,然后得到永久的教訓。
? 也不是所謂的教訓吧,真正的教訓來自于對錯誤的剖析理解很深刻。然后有種“吃一塹,長一智”的感覺才叫教訓。近日和團隊工頭們用CXF3.0和Spring4.0開發一個平臺,模仿著第三方支付,用xml進行數據交互。
? 因此,搜了下。果斷用了dom4j,用自己鍵盤papa打了個叫做XmlOjbUtil的工具類。后來百度下,雖然不是萬能的百度。但也要表揚下,發現人家搭著REST的CXF卻集成了Jaxb。
? 果斷拋棄了!(有時候決定就需要這么果斷。)
先做個鋪墊,我們先說下一些知識點:
? CXF實現webService項目,有兩種模式可以開發。Jax-ws實現經典的Web Service和Jax-rs實現REST標準。在Java EE 5/6中,Jaxb可以方便地集成,負責xml與JavaBean的映射。其實Jaxb也可以作為xml解析的一種技術。
2、認識JAXB
? JAXB(Java Architecture for XML Binding)是根據XML Schema映射到JavaBean的技術。過程中,JAXB將XML實例文檔反向生成Java對象樹的方法,并能將Java對象樹的內容重新寫到 XML實例文檔。
? 在JDK1.6時,JAXB 2.0是JDK 1.6的組成部分。JAXB 2.2.3是JDK 1.7的組成部分。
提前修一下文檔知識吧:
? JDK中JAXB相關的重要CLASS和INTERFACE:
? 1、JAXBContext類,是應用的入口,用于管理XML/Java綁定信息。
? 2、Marshaller接口,將Java對象序列化為XML數據。
? 3、Unmarshaller接口,將XML數據反序列化為Java對象。
?
? JDK中JAXB相關的重要ANNOTATION:
??1、@XmlType,將Java類或枚舉類型映射到XML模式類型
??2、@XmlAccessorType(XmlAccessType.FIELD) ,控制字段或屬性的序列化。FIELD表示JAXB將自動綁定Java類中的每個非靜態的(static)、非瞬態的(由@XmlTransient標注)字段到XML。其他值還有XmlAccessType.PROPERTY和XmlAccessType.NONE。
??3、@XmlAccessorOrder,控制JAXB 綁定類中屬性和字段的排序。
??4、@XmlJavaTypeAdapter,使用定制的適配器(即擴展抽象類XmlAdapter并覆蓋marshal()和unmarshal()方法),以序列化Java類為XML。
??5、@XmlElementWrapper?,對于數組或集合(即包含多個元素的成員變量),生成一個包裝該數組或集合的XML元素(稱為包裝器)。
??6、@XmlRootElement,將Java類或枚舉類型映射到XML元素。
??7、@XmlElement,將Java類的一個屬性映射到與屬性同名的一個XML元素。
??8、@XmlAttribute,將Java類的一個屬性映射到與屬性同名的一個XML屬性。
?
?
3、代碼實戰
我們既然要設計報文,所以我這邊拿出來一個注冊的Bean的設計。首先我們設計注冊的Bean,代碼如下:
DataBean.java
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | package com.xidian.wq.imaopay.model.mesdata.base; import javax.xml.bind.annotation.XmlRootElement; /** ?* ?* @author BYSocket ?* 報文頭-[報文基礎信息] ?*/ @XmlRootElement(name="data_bean") public class DataBean { ????// 版本信息(data_version) ????String version; ????? ????消息類型(data_type) ????// 000001 - 注冊[個人信息Post|Respose] ????// 000002 - 綁定銀行卡[首次綁定,保存個人信息] ????// 000003 - 綁定銀行卡[二次,校驗個人信息] ????// 100001 - 支付[錢包支付] ????// 100002 - 查詢 ????// 200001 ????String data_type; ????? ????訂單編號(order_id) ????// 總長20位, 有字母要用大寫 ????String batch_no; ????? ????// 平臺賬號(platform_account) ????String user_name; ????? ????請求狀態 ????// 000 ????String trans_state; ????? ????// 簽名信息(msg_sign) ????String msg_sign; ????// 時間戳(randomTime) ????private String rd_time; ????// 隨機數(randomNum) ????private String rd_num; ????// 密鑰(keySign) ????private String k_sign; ????? ????// 保留域 ????String reserve; ????public String getVersion() ????{ ????????return version; ????} ????public void setVersion(String version) ????{ ????????this.version = version; ????} ????public String getData_type() ????{ ????????return data_type; ????} ????public void setData_type(String data_type) ????{ ????????this.data_type = data_type; ????} ????public String getBatch_no() ????{ ????????return batch_no; ????} ????public void setBatch_no(String batch_no) ????{ ????????this.batch_no = batch_no; ????} ????public String getUser_name() ????{ ????????return user_name; ????} ????public void setUser_name(String user_name) ????{ ????????this.user_name = user_name; ????} ????public String getTrans_state() ????{ ????????return trans_state; ????} ????public void setTrans_state(String trans_state) ????{ ????????this.trans_state = trans_state; ????} ????public String getMsg_sign() ????{ ????????return msg_sign; ????} ????public void setMsg_sign(String msg_sign) ????{ ????????this.msg_sign = msg_sign; ????} ????public String getRd_time() ????{ ????????return rd_time; ????} ????public void setRd_time(String rd_time) ????{ ????????this.rd_time = rd_time; ????} ????public String getRd_num() ????{ ????????return rd_num; ????} ????public void setRd_num(String rd_num) ????{ ????????this.rd_num = rd_num; ????} ????public String getK_sign() ????{ ????????return k_sign; ????} ????public void setK_sign(String k_sign) ????{ ????????this.k_sign = k_sign; ????} ????public String getReserve() ????{ ????????return reserve; ????} ????public void setReserve(String reserve) ????{ ????????this.reserve = reserve; ????} } |
RegBean.java
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | package com.xidian.wq.imaopay.model.mesdata.base; import javax.xml.bind.annotation.XmlRootElement; /** ?* ?* @author BYSocket ?* 報文體-[用戶注冊報文體信息] ?*/ @XmlRootElement(name="reg_bean") public class RegBean { ????? ????// 注冊報文體流水號(reg_data_sn) ????private String reg_sn; ????? ????用戶編號(user_info_id) ????// 業務系統的用戶編號只做記錄不在支付系統中邏輯處理 ????private Integer user_id; ????// 注冊賬號(reg_account) ????private String reg_no; ????? ????// 注冊途徑(reg_way) ????private String reg_way; ????? ????// 保留域 ????private String reserve; ????? ????提交日期(set_time) ????// 業務系統上傳 ????private String set_time; ????? ????// 后臺信息返回路徑(return_url) ????private String ret_url; ????? ????// 備注 ????String remarks; ????public String getReg_sn() ????{ ????????return reg_sn; ????} ????public void setReg_sn(String reg_sn) ????{ ????????this.reg_sn = reg_sn; ????} ????public Integer getUser_id() ????{ ????????return user_id; ????} ????public void setUser_id(Integer user_id) ????{ ????????this.user_id = user_id; ????} ????public String getReg_no() ????{ ????????return reg_no; ????} ????public void setReg_no(String reg_no) ????{ ????????this.reg_no = reg_no; ????} ????public String getReg_way() ????{ ????????return reg_way; ????} ????public void setReg_way(String reg_way) ????{ ????????this.reg_way = reg_way; ????} ????public String getReserve() ????{ ????????return reserve; ????} ????public void setReserve(String reserve) ????{ ????????this.reserve = reserve; ????} ????public String getSet_time() ????{ ????????return set_time; ????} ????public void setSet_time(String set_time) ????{ ????????this.set_time = set_time; ????} ????public String getRet_url() ????{ ????????return ret_url; ????} ????public void setRet_url(String ret_url) ????{ ????????this.ret_url = ret_url; ????} ????public String getRemarks() ????{ ????????return remarks; ????} ????public void setRemarks(String remarks) ????{ ????????this.remarks = remarks; ????} } |
?
注冊報文體MsgRegBean.java,支持內容的列表。
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | package com.xidian.wq.imaopay.model.mesdata; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import com.xidian.wq.imaopay.model.mesdata.base.DataBean; import com.xidian.wq.imaopay.model.mesdata.base.RegBean; @XmlRootElement( name = "msg_bean" ) public class MsgRegBean { ????private DataBean dataBean; ????? ????private List<RegBean> regBeans; ????? ????public DataBean getDataBean() ????{ ????????return dataBean; ????} ????@XmlElement(name = "data_bean") ????public void setDataBean(DataBean dataBean) ????{ ????????this.dataBean = dataBean; ????} ????@XmlElementWrapper(name = "reg_beans")? ????@XmlElement(name = "reg_bean") ????public List<RegBean> getRegBeans() ????{ ????????return regBeans; ????} ????public void setRegBeans(List<RegBean> regBeans) ????{ ????????this.regBeans = regBeans; ????} } |
然后針對的我們用Jaxb實現一個轉換的Util類:
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | package com.xidian.wq.imaopay.util; 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 com.alibaba.fastjson.JSON; import com.xidian.wq.imaopay.model.mesdata.MsgRegBean; import com.xidian.wq.imaopay.model.mesdata.base.DataBean; import com.xidian.wq.imaopay.model.mesdata.base.RegBean; /** ?*?? ?* @author BYSocket ?* Jaxb2.0 處理Xml與Object轉換 ?* ?*/ public class JaxbObjectAndXmlUtil {? ??????? ????/** ?????* @param xmlStr 字符串 ?????* @param c 對象Class類型 ?????* @return 對象實例 ?????*/ ????@SuppressWarnings("unchecked") ????public static <T> T xml2Object(String xmlStr,Class<T> c) ????{? ????????try ????????{? ????????????JAXBContext context = JAXBContext.newInstance(c);? ????????????Unmarshaller unmarshaller = context.createUnmarshaller();? ????????????? ????????????T t = (T) unmarshaller.unmarshal(new StringReader(xmlStr));? ????????????? ????????????return t;? ????????????? ????????} catch (JAXBException e) {? e.printStackTrace();? return null; }? ????????? ????}? ??????? ????/** ?????* @param object 對象 ?????* @return 返回xmlStr ?????*/ ????public static String object2Xml(Object object) ????{? ????????try ????????{??? ????????????StringWriter writer = new StringWriter(); ????????????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.setProperty("jaxb.encoding", "utf-8");? ????????????marshal.marshal(object,writer); ????????????? ????????????return new String(writer.getBuffer()); ????????????? ????????} catch (Exception e) { e.printStackTrace(); return null;}???? ????????? ????}? ????? ????public static void main(String[] args) ????{ ?????????/** 構造測試報文頭對象 */ ????????DataBean dataBean = new DataBean(); ????????dataBean.setBatch_no("N20150204"); ????????dataBean.setData_type("000001"); ????????dataBean.setVersion("v1.0"); ????????dataBean.setUser_name("xx"); ????????dataBean.setMsg_sign("未知"); ????????dataBean.setRd_num("6631383"); ????????dataBean.setRd_time("20150204"); ????????dataBean.setK_sign("75CC479AAC09F00BA28F0E968B1BC9D1B90ADCC2"); ????????/** 構造測試報文體對象 */ ????????RegBean regBean = new RegBean(); ????????regBean.setReg_sn("REG20150204"); ????????regBean.setUser_id(12); ????????regBean.setReg_no("33"); ????????regBean.setReg_way("pc"); ????????regBean.setSet_time("20150204 16:18"); ????????regBean.setRet_url("未知"); ????????regBean.setRemarks("無備注"); ????????? ????????MsgRegBean msgBean = new MsgRegBean(); ????????List<RegBean> regBeans = new ArrayList<RegBean>(); ????????regBeans.add(regBean); ????????regBeans.add(regBean); ????????? ????????msgBean.setRegBeans(regBeans); ????????msgBean.setDataBean(dataBean); ????????? ????????String xmlStr = JaxbObjectAndXmlUtil.object2Xml(msgBean);//構造報文 XML 格式的字符串 ????????System.out.println("對象轉xml報文: \n"+xmlStr); ????????? ????????MsgRegBean msgBean2 = JaxbObjectAndXmlUtil.xml2Object(xmlStr, MsgRegBean.class); ????????System.out.println("報文轉xml轉: \n"+JSON.toJSONString(msgBean2)); ????} } |
?
運行下測試main函數,可以得到如下的輸出:
?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 對象轉xml報文: <?xml version="1.0" encoding="utf-8" standalone="yes"?> <msg_bean> ????<data_bean> ????????<batch_no>N20150204</batch_no> ????????<data_type>000001</data_type> ????????<k_sign>75CC479AAC09F00BA28F0E968B1BC9D1B90ADCC2</k_sign> ????????<msg_sign>未知</msg_sign> ????????<rd_num>6631383</rd_num> ????????<rd_time>20150204</rd_time> ????????<user_name>xx</user_name> ????????<version>v1.0</version> ????</data_bean> ????<reg_beans> ????????<reg_bean> ????????????<reg_no>33</reg_no> ????????????<reg_sn>REG20150204</reg_sn> ????????????<reg_way>pc</reg_way> ????????????<remarks>無備注</remarks> ????????????<ret_url>未知</ret_url> ????????????<set_time>20150204 16:18</set_time> ????????????<user_id>12</user_id> ????????</reg_bean> ????????<reg_bean> ????????????<reg_no>33</reg_no> ????????????<reg_sn>REG20150204</reg_sn> ????????????<reg_way>pc</reg_way> ????????????<remarks>無備注</remarks> ????????????<ret_url>未知</ret_url> ????????????<set_time>20150204 16:18</set_time> ????????????<user_id>12</user_id> ????????</reg_bean> ????</reg_beans> </msg_bean> 報文轉xml轉: {"dataBean":{"batch_no":"N20150204","data_type":"000001","k_sign":"75CC479AAC09F00BA28F0E968B1BC9D1B90ADCC2","msg_sign":"未知","rd_num":"6631383","rd_time":"20150204","user_name":"xx","version":"v1.0"},"regBeans":[{"reg_no":"33","reg_sn":"REG20150204","reg_way":"pc","remarks":"無備注","ret_url":"未知","set_time":"20150204 16:18","user_id":12},{"reg_no":"33","reg_sn":"REG20150204","reg_way":"pc","remarks":"無備注","ret_url":"未知","set_time":"20150204 16:18","user_id":12}]} |
代碼中間注意點:
? Marshaller.JAXB_FORMATTED_OUTPUT :決定是否在轉換成xml時同時進行格式化(即按標簽自動換行,否則即是一行的xml)?。
? Marshaller.JAXB_ENCODING :xml的編碼方式。
? Marshaller.JAXB_FRAGMENT :是否省略xml頭信息
? marshal.setProperty("jaxb.encoding", "utf-8"); : 設置編碼格式 utf-8
總結
以上是生活随笔為你收集整理的[CXF REST标准实战系列] 一、JAXB xml与javaBean的转换(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习资料合计(二)
- 下一篇: Ruby离线安装gem依赖