美文网首页
XStream介绍

XStream介绍

作者: 拼搏男孩 | 来源:发表于2020-07-04 17:58 被阅读0次

    XStream是一个实现javaBean与XML互相转换的工具,极大地简化了开发人员的对XML的处理

    1、添加依赖

    <dependency>
        <groupId>com.thoughtworks.xstream</groupId>
        <artifactId>xstream</artifactId>
        <version>1.4.11.1</version>
    </dependency>
    

    2、UML类图

    <Document TaskGuid="560eec8a-be14-4398-8c9a-73b68651a129" DataGuid="" DataType=" QueryJYYKTByHourList" >
        <Data>
            <KBH Type="TEXT">卡编号</KBH>
            <DEALRQ Type="TEXT">刷卡日期</DEALRQ>
            <DEALSJ Type="TEXT">刷卡时间</DEALSJ>
            <XLBM Type="TEXT">线路编码</XLBM>
        </Data>
        <Data>
            <KBH Type="TEXT">卡编号</KBH>
            <DEALRQ Type="TEXT">刷卡日期</DEALRQ>
            <DEALSJ Type="TEXT">刷卡时间</DEALSJ>
            <XLBM Type="TEXT">线路编码</XLBM>
        </Data>
    …数据重复出现
    </Document> 
    
    

    假设现在需要将上面的xml转换为一个JavaBean,那么首先需要分析这个XML的结构,根节点是Document,有三个属性TaskGuid、DataGuid、DataType,有许多个子节点Data,每个Data节点都有四个子节点:KBH、DEALRQ、DEALSJ、XLBM。可以采用这种思路:用一个Document类:有四个字段,TaskGuid、DataGuid、DataType与一个Data的集合。每一个Data都有四个字段:KBH、DEALRQ、DEALSJ、XLBM,每个字段都有一个Type和一个值。

    UML类图如下:

    类的关系.png

    Document和Data是聚合关系,Data脱离了Document可以独立存在,Data和Kbh、Dealrq、Dealsj与Xlbm是组合关系,这四个脱离了Data就不能独立存在。

    3、XStream注解

    主要使用
    @XStreamAlias(“alis”)java对象在xml中以标签的形式显示时,如果名字与类名或者属性名不一致,可以使用该标签并在括号内注明别名。
    @XStreamOmitField在输出XML的时候忽略该属性
    @XStreamImplicit如果该属性是一个列表或者数组,在XML中不显示list或者Array字样
    @XStreamAsAttribute该属性不单独显示成XML节点,而是作为属性显示出来
    @XStreamConverter设置转换器
    @XStreamConverters converter主要用于将某些字段进行复杂的转换,转换过程写在一个类中。
    然后将其注册到XStream。

    工具类:

    public class XsteamUtil {
        public static Object toBean(Class<?> clazz, String xml) {
            Object xmlObject = null;
                XStream xstream = new XStream();
                xstream.processAnnotations(clazz);
                xstream.autodetectAnnotations(true);
                xmlObject= xstream.fromXML(xml);
                return xmlObject;
        }
    }
    

    在SpringBoot中可以使用@Bean来进行IOC,设置xstream.autodetectAnnotations(true);来处理注解

    如果要进行xml转JavaBean的操作,需要设施xstream.alias()

    4、具体使用

    ReturnResult.java

    import com.thoughtworks.xstream.annotations.XStreamAlias;
    import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
    import com.thoughtworks.xstream.annotations.XStreamImplicit;
    import lombok.Data;
    import lombok.ToString;
    import lombok.experimental.Accessors;
    
    import java.util.List;
    
    @Data
    @ToString
    @Accessors(chain = true)
    @XStreamAlias("Document")
    public class ReturnResult {
        @XStreamAlias("TaskGuid")
        @XStreamAsAttribute
        private String taskGuid;
        @XStreamAlias("DataGuid")
        @XStreamAsAttribute
        private String dataGuid;
        @XStreamAlias("DataType")
        @XStreamAsAttribute
        private String dataType;
        @XStreamImplicit
        private List<Record> records;
    }
    

    使用了@XStreamAlias注解给类与字段起别名,ReturnResult就对应根节点Document,Java代码中变量名提倡使用小写驼峰命名,所以我对字段也使用的别名。@XStreamAsAttribute不将字段作为节点来对待而是作为属性。 @XStreamImplicit不显示最外层的集合的根节点。

    Record.java

    import com.thoughtworks.xstream.annotations.XStreamAlias;
    import lombok.Data;
    import lombok.experimental.Accessors;
    
    @Data
    @Accessors(chain = true)
    @XStreamAlias("Data")
    public class Record {
        @XStreamAlias("KBH")
        private CardNo cardNo;
        @XStreamAlias("DEALRQ")
        private DealDate dealDate;
        @XStreamAlias("DEALSJ")
        private DealTime dealTime;
        @XStreamAlias("XLBM")
        private RouteCode routeCode;
    }
    

    由于XML文件的节点名不够见名知意,所以我使用@XStreamAlias的方式来解决。

    CardNo.java

    import com.thoughtworks.xstream.annotations.XStreamAlias;
    import com.thoughtworks.xstream.annotations.XStreamConverter;
    import com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import lombok.experimental.Accessors;
    
    /**
     * @author huwen
     * 卡编号
     */
    @Data
    @NoArgsConstructor
    @Accessors(chain = true)
    @XStreamAlias("KBH")
    @XStreamConverter(value= ToAttributedValueConverter.class, strings={"value"})
    public class CardNo {
        @XStreamAlias("Type")
        private String type;
        private String value;
    }
    

    一个<KBH Type="TEXT">卡编号</KBH>节点既有属性又有值,所以使用了@XStreamConverter,用xstream自带的转换器进行转换。

    @Test
    public void testReturnResult2(){
        XStream xStream = new XStream();
        //由于使用的注解,将自动检测注解开启
        xStream.autodetectAnnotations(true);
        List<Record> records = new ArrayList<>();
        
        //设置对象的属性值
        CardNo k1 = new CardNo().setType("TEXT").setValue("36283723");
        CardNo k2 = new CardNo().setType("TEXT").setValue("121211");
        DealTime dealTime1 = new DealTime().setType("TEXT").setValue("12");
        DealTime dealTime2 = new DealTime().setType("TEXT").setValue("1");
        DealDate dealDate1 = new DealDate().setType("TEXT").setValue("20200617");
        DealDate dealDate2 = new DealDate().setType("TEXT").setValue("20200520");
        RouteCode routeCode1 = new RouteCode().setType("TEXT").setValue("212");
        RouteCode routeCode2 = new RouteCode().setType("TEXT").setValue("112");
        records.add(new Record().setCardNo(k1).setDealDate(dealDate1).setDealTime(dealTime1).setRouteCode(routeCode1));
        records.add(new Record().setCardNo(k2).setDealDate(dealDate2).setDealTime(dealTime2).setRouteCode(routeCode2));
        ReturnResult result = new ReturnResult().setDataType("QueryJYYKTByHourList").setTaskGuid("560eec8a-be14-4398-8c9a-73b68651a129")
                .setDataGuid("d78whe28eh").setRecords(records);
        
        //转换为xml格式的字符串
        String s = xStream.toXML(result);
        String s1 =
                "<Document TaskGuid=\"560eec8a-be14-4398-8c9a-73b68651a129\" DataGuid=\"d78whe28eh\" DataType=\"QueryJYYKTByHourList\">\n" +
                        "  <Data>\n" +
                        "    <KBH Type=\"TEXT\">36283723</KBH>\n" +
                        "    <DEALRQ Type=\"TEXT\">20200617</DEALRQ>\n" +
                        "    <DEALSJ Type=\"TEXT\">12</DEALSJ>\n" +
                        "    <XLBM Type=\"TEXT\">212</XLBM>\n" +
                        "  </Data>\n" +
                        "  <Data>\n" +
                        "    <KBH Type=\"TEXT\">121211</KBH>\n" +
                        "    <DEALRQ Type=\"TEXT\">20200520</DEALRQ>\n" +
                        "    <DEALSJ Type=\"TEXT\">1</DEALSJ>\n" +
                        "    <XLBM Type=\"TEXT\">112</XLBM>\n" +
                        "  </Data>\n" +
                        "</Document>";
        System.out.println(s);
        System.out.println(xStream.fromXML(s1));
    }
    

    上面的例子将JavaBean转换为xml。

    @Test
        public void testReturnData(){
            XStream xStream = new XStream();
            xStream.autodetectAnnotations(true);
            //必须要加这行代码,否则会报错,找不到这个类
            xStream.alias("Document",ReturnResult.class);
            String s = "<Document TaskGuid=\"560eec8a-be14-4398-8c9a-73b68651a129\" DataGuid=\"dhshdisds89e\" DataType=\"QueryJYYKTByHourList\">\n" +
                    "  <Data>\n" +
                    "    <KBH Type=\"TEXT\">12121</KBH>\n" +
                    "    <DEALRQ Type=\"TEXT\">2020212</DEALRQ>\n" +
                    "    <DEALSJ Type=\"TEXT\">12</DEALSJ>\n" +
                    "    <XLBM Type=\"TEXT\">12</XLBM>\n" +
                    "  </Data>\n" +
                    "  <Data>\n" +
                    "    <KBH Type=\"TEXT\">37612</KBH>\n" +
                    "    <DEALRQ Type=\"TEXT\">2020312</DEALRQ>\n" +
                    "    <DEALSJ Type=\"TEXT\">15</DEALSJ>\n" +
                    "    <XLBM Type=\"TEXT\">23</XLBM>\n" +
                    "  </Data>\n" +
                    "</Document>";
            System.out.println(xStream.fromXML(s));
        }
    

    上面的例子将xml形式的字符串转换为JavaBean,需要注意的是必须要加xStream.alias("Document",ReturnResult.class);这行代码,否则会报com.thoughtworks.xstream.mapper.CannotResolveClassException: Document这个异常。

    可以看出使用XStream的一般步骤:

    1. 创建XStream对象:XStream xStream = new XStream();
    2. 开始自动检测注解:xStream.autodetectAnnotations(true);
    3. 进行转换:fromXML或者toXML

    既让这个XStrem对象经常使用,那么在Spring项目中可以使用Spring IOC将它交给Spring容器进行管理,在需要的时候进行注入即可。

    相关文章

      网友评论

          本文标题:XStream介绍

          本文链接:https://www.haomeiwen.com/subject/zdzuqktx.html