最近作某電商支付項目外接時,遇到須要傳輸XML報文的。上網查,問同行,最終選擇使用XStream插件。很好很強大。貼上代碼總結下。java
下面Demo涉及別名、XML結構、空值處理,仍有不少不完善的地方。能夠查閱某老司機的帖子: JAVA bean與XML互轉的利器---XStream測試
目標報文格式:this
<Service> <Service_Header> <msg_type>YTISSUE</msg_type> <branch_id>QJS201609201547256567816</branch_id> <order_no>LPE20160919103159</order_no> </Service_Header> <Service_Body> <sign_off_time>Mon Sep 19 19:07:02 CST 2016</sign_off_time> <send_cost>20</send_cost> <order_time>Mon Sep 19 18:56:12 CST 2016</order_time> <order_type>1</order_type> <goods_amount>32.8</goods_amount> <order_amount>32.8</order_amount> <Promotions> </Promotions> <Payments> <payment> <payment_method>餘額支付</payment_method> <payment_amount>32.8</payment_amount> </payment> </Payments> <Items> <item> <line_no></line_no> <product_code>0825821001</product_code> <product_name>美國進口 萬多福椒鹽開心果 168g</product_name> <sale_price>32.8</sale_price> <sale_sum>1</sale_sum> <Payments> <payment> <payment_method>餘額支付</payment_method> <payment_amount>32.8</payment_amount> </payment> </Payments> <Promotions> </Promotions> <order_detail_no>LPE201609191031590101</order_detail_no> <payment_method>餘額支付:32.8</payment_method> </item> </Items> </Service_Body> </Service>
報文封裝類 :.net
package com.iokbl.dto.xml.issue; import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 下發ERP報文根節點 * @author tm * @date 2016年9月18日下午1:25:04 */ @XStreamAlias("Service") public class ServiceRootClass { @XStreamAlias("Service_Header") private ServiceHeaderClass header; //報文頭 @XStreamAlias("Service_Body") private ServiceBodyClass body; //報文體 public ServiceHeaderClass getHeader() { return header; } public void setHeader(ServiceHeaderClass header) { this.header = header; } public ServiceBodyClass getBody() { return body; } public void setBody(ServiceBodyClass body) { this.body = body; } }
報文頭類:插件
package com.iokbl.dto.xml.issue; import com.thoughtworks.xstream.annotations.XStreamAlias; /** * ERP下發報文頭結構 * @author tm * @date 2016年9月18日下午1:25:04 */ @XStreamAlias("Service_Header") public class ServiceHeaderClass { @XStreamAlias("msg_type") private String msg_type = ""; //消息類型 @XStreamAlias("branch_id") private String branch_id = ""; //批次號 @XStreamAlias("order_no") private String order_no = ""; //訂單號 public String getMsg_type() { return msg_type; } public void setMsg_type(String msg_type) { this.msg_type = msg_type; } public String getBranch_id() { return branch_id; } public void setBranch_id(String branch_id) { this.branch_id = branch_id; } public String getOrder_no() { return order_no; } public void setOrder_no(String order_no) { this.order_no = order_no; } }
報文體父類:code
package com.iokbl.dto.xml.issue; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamImplicit; import com.thoughtworks.xstream.annotations.XStreamImplicitCollection; /** * ERP下發報文頭結構 * @author tm * @date 2016年9月18日下午1:25:04 */ @XStreamAlias("Service_Body") public class ServiceBodyClass { @XStreamAlias("sign_off_time") private String sign_off_time = ""; //簽收時間 @XStreamAlias("send_cost") private String send_cost = ""; //運費 @XStreamAlias("order_time") private String order_time = ""; //訂單下單時間 @XStreamAlias("order_type") private String order_type = ""; //訂單類型(見字典) @XStreamAlias("goods_amount") private String goods_amount = ""; //商品總金額(不含運費的訂單金額) @XStreamAlias("order_amount") private String order_amount = ""; //訂單實際金額(用戶實際支付金額,包含運費) @XStreamAlias("Promotions") private List<OrderPromotionIssueDto> promList = new ArrayList<OrderPromotionIssueDto>(); //訂單行優惠項明細 @XStreamAlias("Payments") private List<OrderPaymentIssueDto> payList = new ArrayList<OrderPaymentIssueDto>(); //商品支付項明細 @XStreamAlias("Items") private List<ProductBaseIssueDto> itemList = new ArrayList<ProductBaseIssueDto>(); //訂單行商品列表 public String getSign_off_time() { return sign_off_time; } public void setSign_off_time(String sign_off_time) { this.sign_off_time = sign_off_time; } public String getSend_cost() { return send_cost; } public void setSend_cost(String send_cost) { this.send_cost = send_cost; } public String getOrder_time() { return order_time; } public void setOrder_time(String order_time) { this.order_time = order_time; } public String getOrder_type() { return order_type; } public void setOrder_type(String order_type) { this.order_type = order_type; } public String getGoods_amount() { return goods_amount; } public void setGoods_amount(String goods_amount) { this.goods_amount = goods_amount; } public String getOrder_amount() { return order_amount; } public void setOrder_amount(String order_amount) { this.order_amount = order_amount; } public List<OrderPromotionIssueDto> getPromList() { return promList; } public void setPromList(List<OrderPromotionIssueDto> promList) { this.promList = promList; } public List<OrderPaymentIssueDto> getPayList() { return payList; } public void setPayList(List<OrderPaymentIssueDto> payList) { this.payList = payList; } public List<ProductBaseIssueDto> getItemList() { return itemList; } public void setItemList(List<ProductBaseIssueDto> itemList) { this.itemList = itemList; } }
報文體--子類(訂單優惠信息list):xml
package com.iokbl.dto.xml.issue; import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 優惠信息類-訂單緯度 * @author tm * @date 2016年9月18日下午2:45:44 */ @XStreamAlias("promotion") public class OrderPromotionIssueDto { @XStreamAlias("promotion_type") private String promotion_type = ""; //優惠類型 @XStreamAlias("coupon_no") private String coupon_no = ""; //優惠券號 @XStreamAlias("promotion_amount") private String promotion_amount = "";//券承擔方金額 @XStreamAlias("promotion_entities") private String promotion_entities = "";//券承擔方 @XStreamAlias("acitivity_code") private String acitivity_code = ""; //活動編號 @XStreamAlias("acitivity_name") private String acitivity_name = ""; //活動名稱 @XStreamAlias("templet_code") private String templet_code = ""; //模板編號 @XStreamAlias("templet_name") private String templet_name = ""; //模板名稱 public String getPromotion_type() { return promotion_type; } public void setPromotion_type(String promotion_type) { this.promotion_type = promotion_type; } public String getCoupon_no() { return coupon_no; } public void setCoupon_no(String coupon_no) { this.coupon_no = coupon_no; } public String getPromotion_amount() { return promotion_amount; } public void setPromotion_amount(String promotion_amount) { this.promotion_amount = promotion_amount; } public String getPromotion_entities() { return promotion_entities; } public void setPromotion_entities(String promotion_entities) { this.promotion_entities = promotion_entities; } public String getAcitivity_code() { return acitivity_code; } public void setAcitivity_code(String acitivity_code) { this.acitivity_code = acitivity_code; } public String getAcitivity_name() { return acitivity_name; } public void setAcitivity_name(String acitivity_name) { this.acitivity_name = acitivity_name; } public String getTemplet_code() { return templet_code; } public void setTemplet_code(String templet_code) { this.templet_code = templet_code; } public String getTemplet_name() { return templet_name; } public void setTemplet_name(String templet_name) { this.templet_name = templet_name; } }
報文體--子類(訂單支付信息list):對象
package com.iokbl.dto.xml.issue; import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 支付信息-訂單緯度 * @author tm * @date 2016年9月18日下午2:55:21 */ @XStreamAlias("payment") public class OrderPaymentIssueDto { @XStreamAlias("payment_method") private String payment_method = ""; //支付方式 @XStreamAlias("payment_amount") private String payment_amount = ""; //支付金額 public String getPayment_method() { return payment_method; } public void setPayment_method(String payment_method) { this.payment_method = payment_method; } public String getPayment_amount() { return payment_amount; } public void setPayment_amount(String payment_amount) { this.payment_amount = payment_amount; } }
報文體--子類(訂單中某商品的基本信息):blog
package com.iokbl.dto.xml.issue; import java.util.List; import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 訂單行商品明細-商品緯度 * @author tm * @date 2016年9月18日下午2:46:10 */ @XStreamAlias("item") public class ProductBaseIssueDto { @XStreamAlias("line_no") private String line_no = ""; //行編號 @XStreamAlias("product_code") private String product_code = "";//商品編號 @XStreamAlias("product_name") private String product_name = "";//商品名稱 @XStreamAlias("sale_price") private String sale_price = ""; //訂購價(商品售價) @XStreamAlias("sale_sum") private String sale_sum = ""; //訂購量 @XStreamAlias("Payments") private List<ProductPaymentIssueDto> payList; //商品支付項明細 @XStreamAlias("Promotions") private List<ProductPromotionIssueDto> promList; //訂單行優惠項明細 public String getLine_no() { return line_no; } public void setLine_no(String line_no) { this.line_no = line_no; } public String getProduct_code() { return product_code; } public void setProduct_code(String product_code) { this.product_code = product_code; } public String getProduct_name() { return product_name; } public void setProduct_name(String product_name) { this.product_name = product_name; } public String getSale_price() { return sale_price; } public void setSale_price(String sale_price) { this.sale_price = sale_price; } public String getSale_sum() { return sale_sum; } public void setSale_sum(String sale_sum) { this.sale_sum = sale_sum; } public List<ProductPaymentIssueDto> getPayList() { return payList; } public void setPayList(List<ProductPaymentIssueDto> payList) { this.payList = payList; } public List<ProductPromotionIssueDto> getPromList() { return promList; } public void setPromList(List<ProductPromotionIssueDto> promList) { this.promList = promList; } }
報文體--子類(訂單中某商品的優惠信息list):支付寶
package com.iokbl.dto.xml.issue; import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 商品優惠信息類(雖與訂單優惠信息結構一致,但組裝保文時必須新建該對象才能正常顯示指定報文結構。) * @author tm * @date 2016年9月18日下午2:45:44 */ @XStreamAlias("promotion") public class ProductPromotionIssueDto extends OrderPromotionIssueDto{ }
報文體--子類(訂單中某商品的支付信息list):
package com.iokbl.dto.xml.issue; import com.thoughtworks.xstream.annotations.XStreamAlias; /** * 支付信息(雖與訂單支付結構一致,但組裝保文時必須新建該對象才能正常顯示指定報文結構。) * @author tm * @date 2016年9月18日下午2:55:21 */ @XStreamAlias("payment") public class ProductPaymentIssueDto extends OrderPaymentIssueDto{ }
最終測試類:
package com.iokbl.dto.xml.issue; import java.util.ArrayList; import java.util.List; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder; /** * 測試類 * @author tm * @date 2016年9月18日下午1:42:43 */ public class Test { public static void main(String[] args) { //目標對象 ServiceRootClass root = new ServiceRootClass(); ServiceHeaderClass header = new ServiceHeaderClass(); ServiceBodyClass body = new ServiceBodyClass(); header.setMsg_type("MMMM"); header.setBranch_id("4546"); header.setOrder_no("1111111"); body.setGoods_amount("12"); body.setSign_off_time("2016-07-08 15:30:20"); body.setGoods_amount("10"); body.setOrder_amount("111110001"); body.setOrder_time("2016-07-09 15:30:20"); body.setOrder_type("銷售訂單"); body.setSend_cost("成本500"); /** 封裝優惠信息start **/ OrderPromotionIssueDto prom1 = new OrderPromotionIssueDto(); prom1.setAcitivity_code("100001"); prom1.setAcitivity_name("滿200減80"); prom1.setCoupon_no("YHQ1001"); prom1.setPromotion_amount("200"); prom1.setPromotion_entities("YT5201"); prom1.setPromotion_type("滿減"); prom1.setTemplet_code("Template1001"); prom1.setTemplet_name("滿200減80活動模板"); OrderPromotionIssueDto prom2 = new OrderPromotionIssueDto(); prom2.setAcitivity_code("100002"); prom2.setAcitivity_name("全場八折"); prom2.setCoupon_no("ZKZR1001"); prom2.setPromotion_amount("200"); prom2.setPromotion_entities("YT5201"); prom2.setPromotion_type("折扣折讓"); prom2.setTemplet_code("Template1002"); prom2.setTemplet_name("八折模板"); List<OrderPromotionIssueDto> promList = new ArrayList<OrderPromotionIssueDto>(); promList.add(prom1); promList.add(prom2); //封裝優惠信息到報文體 body.setPromList(promList); /** 封裝優惠信息end **/ /** 封裝支付信息start **/ OrderPaymentIssueDto pay = new OrderPaymentIssueDto(); pay.setPayment_method("支付寶"); pay.setPayment_amount("305.00"); List<OrderPaymentIssueDto> payList = new ArrayList<OrderPaymentIssueDto>(); payList.add(pay); body.setPayList(payList); /** 封裝支付信息end **/ /** 封裝商品行信息start **/ List<ProductPaymentIssueDto> subls = new ArrayList<ProductPaymentIssueDto>() ; ProductPaymentIssueDto sub = new ProductPaymentIssueDto() ; sub.setPayment_amount("4545"); sub.setPayment_method("test"); subls.add(sub) ; List<ProductPromotionIssueDto> subPromList = new ArrayList<ProductPromotionIssueDto>(); ProductPromotionIssueDto subPromDto = new ProductPromotionIssueDto(); subPromDto.setAcitivity_code("100001"); subPromDto.setAcitivity_name("滿200減80"); subPromDto.setCoupon_no("YHQ1001"); subPromDto.setPromotion_amount("200"); subPromDto.setPromotion_entities("YT5201"); subPromDto.setPromotion_type("滿減"); subPromDto.setTemplet_code("Template1001"); subPromDto.setTemplet_name("滿200減80活動模板"); subPromList.add(subPromDto); ProductBaseIssueDto item1 = new ProductBaseIssueDto(); item1.setLine_no("518"); item1.setProduct_code("PRD1001"); item1.setProduct_name("德芙巧克力"); item1.setSale_price("26.40"); item1.setSale_sum("5"); item1.setPromList(subPromList); item1.setPayList(subls); List<ProductBaseIssueDto> itemList = new ArrayList<ProductBaseIssueDto>(); itemList.add(item1); body.setItemList(itemList); /** 封裝商品行信息end **/ root.setHeader(header); root.setBody(body); XStream x = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_"))); x.autodetectAnnotations(true); String xml = x.toXML(root); System.out.println(xml); } }
----以上Test.java,親測有效。
開發期間遇到坑:
一、XStream對空值不輸出成對標籤,單個值可經過聲明時添加默認空值實現,但List爲空時,坑還沒填上……