在一次調用webservice接口時,因為webservice通信的主要報文格式為xml,如果通過直接拼接字符串的方式來生成xml,則會導致代碼特別混亂;並且由於字符串大量拼接也會占用JVM大量內存,我們是不是應該有一種類似於java bean轉json這樣子優雅的方式來講java bean轉成xml報文呢?答案是肯定的,它就是Xstream。
Xstream的官方地址為http://x-stream.github.io/index.html
Xstream的結構組件:
1. 轉換器(Converters)
Xstream內置了大量的converters將java bean轉換為xml,如JavaBeanConverter等。
2. 驅動(Drivers (Writer and Reader))
實現了從流中讀取xml
3. 上下文(Context)
4. 外觀(Facade)
實際應用Xstream
1. 創建XstreamUtils工具類,代碼如下
package com.hibase.common.utils; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; /** * xstream工具類 * * @author hufeng * @date 2019/07/09 */ public class XStreamUtils { private XStreamUtils() { } /** * 通過靜態內部類實現單例模式 */ private static class LazyHolder { private static final XStreamUtils INSTANCE = new XStreamUtils(); } private static class SingletonXstream { private static XStream xStream = null; static { if (xStream == null) { xStream = new XStream(new DomDriver()); // 去掉class屬性 xStream.aliasSystemAttribute(null, "class"); //避免出現以下警告:Security framework of XStream not initialized, XStream is probably vulnerable XStream.setupDefaultSecurity(xStream); } } } public static XStream getInstance() { return SingletonXstream.xStream; } /** * 對象直接轉換為XML字符串格式 * * @param t * @param <T> * @return */ public static <T> String toXml(T t) { XStream xstream = XStreamUtils.getInstance(); xstream.allowTypeHierarchy(t.getClass()); xstream.processAnnotations(t.getClass()); return xstream.toXML(t); } /** * XML直接轉化為對象 * * @param xml * @param clazz * @param <T> * @return */ @SuppressWarnings("unchecked") public static <T> T toBean(String xml, Class<T> clazz) { XStream xstream = XStreamUtils.getInstance(); xstream.allowTypeHierarchy(clazz); xstream.processAnnotations(clazz); T obj = (T) xstream.fromXML(xml); return obj; } }
2. 創建java bean,代碼如下
package com.hichain.tms.api.entity.soap.request; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamImplicit; import lombok.Data; import org.hibernate.validator.constraints.NotBlank; import java.util.List; /** * OA生成賬單vo * * @author hufeng * @date 2019/07/09 */ @Data @XStreamAlias("ser:setReimbursementByTms") public class OaBillVO { /** * 工號 */ @NotBlank(message = "提交人不能為空") private String userNo; /** * 報銷人工號 */ @NotBlank(message = "提交人不能為空") private String bxUserNo; /** * 請款類型 */ @NotBlank(message = "付款對象類型不能為空") private String applyType; /** * 支付公司CODE */ @NotBlank(message = "付款對象類型不能為空") private String payCompanyId; /** * 支付對象CODE */ @NotBlank(message = "付款對象不能為空") private String payObiectId; /** * 產品類型CODE */ @NotBlank(message = "產品類型不能為空") private String productTypeId; /** * 費用科目CODE */ @NotBlank(message = "費用科目不能為空") private String costSubjectsId; /** * 利潤中心CODE */ @NotBlank(message = "利潤中心不能為空") private String profitCenterId; /** * 幣別 */ @NotBlank(message = "實付幣種不能為空") private String invoiceCurrency; /** * 發票金額 */ @NotBlank(message = "實付金額不能為空") private String invoiceAmount; /** * 事由 */ @NotBlank(message = "事由不能為空") private String cause; /** * 備注 */ @NotBlank(message = "備注不能為空") private String remarks; /** * 付款幣別 */ @NotBlank(message = "實付幣種不能為空") private String payCurrency; /** * 付款金額 */ @NotBlank(message = "實付金額不能為空") private String payAmount; /** * 沖借款對象 */ @XStreamImplicit(itemFieldName = "offsetLoan") private List<OaBillRushedVO> oaBillRushedVOs; }
測試main代碼
package com.hichain.tms.utils; import com.hibase.common.utils.XStreamUtils; import com.hichain.tms.api.entity.soap.request.OaBillRushedVO; import com.hichain.tms.api.entity.soap.request.OaBillVO; import java.util.Arrays; import java.util.List; /** * 發送OA soap工具類 * * @author hufeng * @date 2019/07/09 */ public class Test { private Test() { } /** * 生成OA SOAP報文 * * @param oaBillVO * @return */ public static String buildSoapMessage(OaBillVO oaBillVO) { return XStreamUtils.toXml(oaBillVO); } public static void main(String[] args) { OaBillVO oaBillVOArg0 = new OaBillVO(); oaBillVOArg0.setPayObiectId("12313"); oaBillVOArg0.setApplyType("12313"); OaBillRushedVO oaBillRushedVO = new OaBillRushedVO(); oaBillRushedVO.setLoanNo("123"); oaBillRushedVO.setOffsetAmount("123.23"); OaBillRushedVO oaBillRushedVO1 = new OaBillRushedVO(); oaBillRushedVO1.setLoanNo("234"); oaBillRushedVO1.setOffsetAmount("234.23"); List<OaBillRushedVO> billRushedVOS = Arrays.asList(oaBillRushedVO, oaBillRushedVO1); oaBillVOArg0.setOaBillRushedVOs(billRushedVOS); System.out.println(buildSoapMessage(oaBillVOArg0)); } }