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

官方网站: http://xstream.codehaus.org/

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

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

接收xml的泛型对象:

@XStreamAlias ( "RESPONSE" )
public class Response {
@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 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.get Class() ) ;
          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 > appleman 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实现类进行处理

你可能感兴趣的:(xstream)