使用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實現類進行處理
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章