今天在做一个基于XML报文的通信接口的时候,遇到了一个小问题,在这个XML里面,客户定义了一个纯String的List,如下所示
<root>
<desc>this is only a example</desc>
<namelist>
<name>user01</name>
<name>user02</name>
<name>user03</name>
</namelist>
</root>
第一眼看到这个list,想当然的是用 @XStreamAlias(value = "namelist", impl = List.class)来处理了,于是定义了一个Bean
@XStreamAlias("root")
public class Rootinfo()
{
@XStreamAlias("desc")
private String desc;
@XStreamAlias(value = "namelist", impl = List.class)
private List<String> nameList;
}
结果自然是…… 不行。 因为这种方式是对待复杂对象的,如果是下面这样的XML
<root>
<desc>this is an example 2</desc>
<namelist>
<name>
<fname>fname01</fname>
<lname>lname01</lname>
</name>
<name>
<fname>fname02</fname>
<lname>lname02</lname>
</name>
</namelist>
</root>
以及这样的类定义的时候
@XStreamAlias("root")
public class Rootinfo()
{
@XStreamAlias("desc")
private String desc;
@XStreamAlias(value = "namelist", impl = List.class)
private List<nameBean> nameList;
}
@XStreamAlias(value = "name")
public class NameBean()
{
@XStreamAlias(value = "fname")
private String fname;
@XStreamAlias(value = "lname")
private String lname;
}
这个时候是可以的,而对于单纯的List<String>这种定义是无效的。
于是,又想到了另外一个注解,@XStreamImplicit(itemFieldName ="name")
这一下好了,结果————仍然不行。
XStreamImplicit注解会剔除外层的元素,也就是说对于XStreamImplicit这个注解 XML如果是这样,是可以识别的
<root>
<desc>this is only a example</desc>
<name>user01</name>
<name>user02</name>
<name>user03</name>
</root>
但是如果有了外层包围,就不行了。
连试了量中方法都不行,颇有些挫败感。于是去查了一下XStream的文档,没有合适的注解来处理这种情况。所以只好另外想办法,没办法,只能辛辛苦苦用解放前的招数了,上Converter!!!
XStream xstream = new XStream(new DomDriver());
xstream.processAnnotations(Rootinfo.class);
ClassAliasingMapper mapper = new ClassAliasingMapper(xstream.getMapper());
mapper.addClassAlias("name", String.class);
xstream.registerLocalConverter(
Rootinfo.class, "namelist",
new CollectionConverter(mapper)
);
Rootinfo strXML=(Rootinfo)xstream.fromXML(strXML);
首先为String类型的数据生成一个别名 name, 然后在指明这个别名 只在namelist这个标签中生效,然后进行转换。
然后,在类的字段上,使用正常的别名注解,也就是
@XStreamAlias("root")
@Data
class Rootinfo
{
@XStreamAlias("desc")
private String desc;
@XStreamAlias("namelist")
private List<String> namelist;
}
就可以了
这样,如果一个XML文件中,由多个这样的List的话,可以分别指明每一个List中 的别名,从而可以处理如下例所示的XML
<root>
<desc>this is only a example</desc>
<namelist>
<name>user01</name>
<name>user02</name>
<name>user03</name>
</namelist>
<infolist>
<info>info01</info>
<info>info02</info>
<info>info03</info>
</infolist>
</root>
通过指明每一个别名的作用域,可以让不同的List<String>拥有不同的别名,以免出现所有的string都被转成一种名字的情况。