使用xstream解析XML转换成带泛型的对象


xml样例:
String xml1 = “<RESPONSE><ERRORINFO></ERRORINFO><RETINFO><FRUITS><FRUIT><Name>apple</Name></FRUIT><FRUIT><Name>banana</Name></FRUIT></FRUITS></RETINFO></RESPONSE>” ;

被抽象的xml内容体:
public interface RETINFO {
}

接收xml的泛型对象:

@XStreamAlias("RESPONSE")
public class Response <T extends RETINFO>{
@XStreamAlias("ERRORINFO")
private ErrorInfo errorInfo;
@XStreamAlias("RETINFO")
private T retInfo;

//getter/setter
}

泛型的实现类

@XStreamAlias("RETINFO")
public class RetInfo_FRUITS implements RETINFO{
@XStreamAlias("FRUITS")
List<FRUIT> FRUITS = null ;

//getter/setter
}

@XStreamAlias("FRUIT")
public class FRUIT {
@XStreamAlias("Name")
String  Name = null ;

//getter/setter
}


方法1:通过类型转换器实现泛型的转换

类型转换器:
  1. canConvert方法中判断当前的类是否为我们要转换的类型,不是则返回false,如果是就返回true
  2. unmarshal反序列化方法中,将实际使用的类return回去。
  3. 如果实现类的层级比较深,则需要使用context.convertAnother方法将当前节点以下的声明同步转换了。不然无法识别到子节点信息。

@XStreamConverter(FruitConvert.class)
public class FruitConvert extends Response<RetInfo> implements Converter{
@Override
public boolean canConvert(Class clazz) {
    return clazz.equals(RETINFO.class);
}

@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {

    RetInfo_FRUITS retinfo = new RetInfo_FRUITS();
    context.convertAnother(retinfo, retinfo.getClass()) ;
        return retinfo ;
}
}


如果在当前的工程中,只有一个接口实现类,就可以用这种方法。
例如:在微服务中,每个功能打包部署成一个独立应用,那么每个功能接口都可以用一个自己的实现类。

测试类

public class Test{
public static void main(String[] args) {

    XStream xstream = new XStream();
    xstream.processAnnotations(new Class[] {Response.class,RetInfo_FRUITS.class});
    xstream.autodetectAnnotations(true);
    Response<RetInfo_FRUITS> resp = xstream.fromXML(xml);
    System.out.println(resp.toString());

}


调用者必须将所有用到的类按照xml的层级结构添加上@XStreamAlias标签
但是,对于抽象的泛型,还需要在processAnnotations中单独添加实现接口的class才行



方法2:通过添加class属性实现泛型的转换

String xml2 = “<RESPONSE><ERRORINFO></ERRORINFO><RETINFO><Name>apple</Name><Sex>man</Sex></RETINFO></RESPONSE>” ;

对于xml体量比较小的,还可以使用添加class属性的方式实现

xml2 = xml2.replace("<RETINFO>",<RETINFO class=‘com.xx.RetInfo_Person'>”);

@XStreamAlias("RETINFO")
public class RetInfo_Person implements RETINFO{
@XStreamAlias("Name")
String Name = null ;
@XStreamAlias("Sex")
String Sex = null ;

//getter/setter
}

测试类

public class Test{
public static void main(String[] args) {

    XStream xstream = new XStream();
    xstream.processAnnotations(new Class[] {Response.class});
    xstream.autodetectAnnotations(true);
    Response<RetInfo_Person> resp = xstream.fromXML(xml);
    System.out.println(resp.toString());

}

利用增加class属性的方法可以仅对最外层的xml实现类进行处理
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章