xstream--------优雅的构造xml和解析xml
在一次调用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)); } }