XStream介绍

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

1、添加依赖


    com.thoughtworks.xstream
    xstream
    1.4.11.1

2、UML类图


    
        卡编号
        刷卡日期
        刷卡时间
        线路编码
    
    
        卡编号
        刷卡日期
        刷卡时间
        线路编码
    
…数据重复出现
 

假设现在需要将上面的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 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;
}

一个卡编号节点既有属性又有值,所以使用了@XStreamConverter,用xstream自带的转换器进行转换。

@Test
public void testReturnResult2(){
    XStream xStream = new XStream();
    //由于使用的注解,将自动检测注解开启
    xStream.autodetectAnnotations(true);
    List 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 =
            "\n" +
                    "  \n" +
                    "    36283723\n" +
                    "    20200617\n" +
                    "    12\n" +
                    "    212\n" +
                    "  \n" +
                    "  \n" +
                    "    121211\n" +
                    "    20200520\n" +
                    "    1\n" +
                    "    112\n" +
                    "  \n" +
                    "";
    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 = "\n" +
                "  \n" +
                "    12121\n" +
                "    2020212\n" +
                "    12\n" +
                "    12\n" +
                "  \n" +
                "  \n" +
                "    37612\n" +
                "    2020312\n" +
                "    15\n" +
                "    23\n" +
                "  \n" +
                "";
        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介绍)