在上一节中,我们已经看到了XStream是多么的简单易用,本文将继续以实例的方式讲解XStream别名。毕竟,你的JAVA对象不可能总是与XML结构毫发无差的,谁也不确定某个开发者手误打错了字母,或者是报文的名称发生了变化。


假设输出如下的XML结构,我们应该怎么做呢?

<blogauthor="一个木瓜"><entry><title>第一篇</title><description>欢迎来到木瓜博客!</description></entry><entry><title>第二篇</title><description>全国启动防雾霾红色预警。</description></entry></entries></blog>


1. 根据XML结构构建JAVA对象

packagecom.favccxx.favsoft.pojo;importjava.util.ArrayList;importjava.util.List;publicclassBlog{privateAuthorwriter;privateList<Entry>entries=newArrayList<Entry>();publicBlog(Authorwriter){this.writer=writer;}publicvoidadd(Entryentry){entries.add(entry);}publicvoidaddEntry(Entryentry){entries.add(entry);}publicList<Entry>getContent(){returnentries;}publicAuthorgetWriter(){returnwriter;}publicvoidsetWriter(Authorwriter){this.writer=writer;}}


packagecom.favccxx.favsoft.pojo;publicclassEntry{privateStringtitle;privateStringdescription;publicEntry(Stringtitle,Stringdescription){this.title=title;this.description=description;}publicStringgetTitle(){returntitle;}publicvoidsetTitle(Stringtitle){this.title=title;}publicStringgetDescription(){returndescription;}publicvoidsetDescription(Stringdescription){this.description=description;}}


2.开始代码测试

packagecom.favccxx.favsoft.main;importcom.favccxx.favsoft.pojo.Author;importcom.favccxx.favsoft.pojo.Blog;importcom.favccxx.favsoft.pojo.Entry;importcom.thoughtworks.xstream.XStream;publicclassMainBlog{publicstaticvoidmain(Stringargs[]){BlogmyBlog=newBlog(newAuthor("一个木瓜"));myBlog.add(newEntry("第一篇","欢迎来到木瓜博客!"));myBlog.add(newEntry("第二篇","全国启动防雾霾红色预警。"));XStreamxstream=newXStream();System.out.println(xstream.toXML(myBlog));}}


3.发现输出内容结构并不是想象的那样,怎么办?

<com.favccxx.favsoft.pojo.Blog><writer><name>一个木瓜</name></writer><entries><com.favccxx.favsoft.pojo.Entry><title>第一篇</title><description>欢迎来到木瓜博客!</description></com.favccxx.favsoft.pojo.Entry><com.favccxx.favsoft.pojo.Entry><title>第二篇</title><description>全国启动防雾霾红色预警。</description></com.favccxx.favsoft.pojo.Entry></entries></com.favccxx.favsoft.pojo.Blog>


4.使用类别名,将包含路径的类对象进行替换。

xstream.alias("blog",Blog.class);xstream.alias("entry",Entry.class);


发现输出结构与想要的结构近了一点,但还是不满足要求。

<blog><writer><name>一个木瓜</name></writer><entries><entry><title>第一篇</title><description>欢迎来到木瓜博客!</description></entry><entry><title>第二篇</title><description>全国启动防雾霾红色预警。</description></entry></entries></blog>


5. 使用字段别名,将写手writer改成作者author,发现输出结构又近了一层。

xstream.aliasField("author",Blog.class,"writer");


<blog><author><name>一个木瓜</name></author><entries><entry><title>第一篇</title><description>欢迎来到木瓜博客!</description></entry><entry><title>第二篇</title><description>全国启动防雾霾红色预警。</description></entry></entries></blog>


6. 使用隐式集合,将不需要展示的集合的根节点进行隐藏。需要注意的是数组和MAP结合不能声明成隐式集合。

xstream.addImplicitCollection(Blog.class,"entries");


<blog><author><name>一个木瓜</name></author><entry><title>第一篇</title><description>欢迎来到木瓜博客!</description></entry><entry><title>第二篇</title><description>全国启动防雾霾红色预警。</description></entry></blog>


7. 使用属性别名,将xml中的成员对象以属性标签形式展示。但是属性标签并不会直接写到xml标签上去,需要实现SingleValueConverter转换器才行。

xstream.useAttributeFor(Blog.class,"writer");xstream.aliasField("author",Blog.class,"writer");


packagecom.favccxx.favsoft.util;importcom.favccxx.favsoft.pojo.Author;importcom.thoughtworks.xstream.converters.SingleValueConverter;publicclassAuthorConverterimplementsSingleValueConverter{@OverridepublicbooleancanConvert(Classtype){returntype.equals(Author.class);}@OverridepublicStringtoString(Objectobj){return((Author)obj).getName();}@OverridepublicObjectfromString(Stringstr){returnnewAuthor(str);}}


8.终于改完了,最终的完整代码是这样的

packagecom.favccxx.favsoft.main;importcom.favccxx.favsoft.pojo.Author;importcom.favccxx.favsoft.pojo.Blog;importcom.favccxx.favsoft.pojo.Entry;importcom.favccxx.favsoft.util.AuthorConverter;importcom.thoughtworks.xstream.XStream;publicclassMainBlog{publicstaticvoidmain(Stringargs[]){BlogmyBlog=newBlog(newAuthor("一个木瓜"));myBlog.add(newEntry("第一篇","欢迎来到木瓜博客!"));myBlog.add(newEntry("第二篇","全国启动防雾霾红色预警。"));XStreamxstream=newXStream();xstream.alias("blog",Blog.class);xstream.alias("entry",Entry.class);xstream.useAttributeFor(Blog.class,"writer");xstream.aliasField("author",Blog.class,"writer");xstream.registerConverter(newAuthorConverter());xstream.addImplicitCollection(Blog.class,"entries");System.out.println(xstream.toXML(myBlog));}}


9.输出完美的XML结构

<blogauthor="一个木瓜"><entry><title>第一篇</title><description>欢迎来到木瓜博客!</description></entry><entry><title>第二篇</title><description>全国启动防雾霾红色预警。</description></entry></blog>


10.有时候需要使用包别名,将包名进行替换。需要替换的包名必须从首字母开始替换,不能从中间开始查找替换。

packagecom.favccxx.favsoft.main;importcom.favccxx.favsoft.pojo.Author;importcom.favccxx.favsoft.pojo.Blog;importcom.favccxx.favsoft.pojo.Entry;importcom.thoughtworks.xstream.XStream;publicclassMainBlog{publicstaticvoidmain(Stringargs[]){BlogmyBlog=newBlog(newAuthor("一个木瓜"));myBlog.add(newEntry("第一篇","欢迎来到木瓜博客!"));myBlog.add(newEntry("第二篇","全国启动防雾霾红色预警。"));XStreamxstream=newXStream();xstream.aliasPackage("my.company","com.favccxx");System.out.println(xstream.toXML(myBlog));}}


11.输出格式如下

<my.company.favsoft.pojo.Blog><writer><name>一个木瓜</name></writer><entries><my.company.favsoft.pojo.Entry><title>第一篇</title><description>欢迎来到木瓜博客!</description></my.company.favsoft.pojo.Entry><my.company.favsoft.pojo.Entry><title>第二篇</title><description>全国启动防雾霾红色预警。</description></my.company.favsoft.pojo.Entry></entries></my.company.favsoft.pojo.Blog>


小结:

可以使用类别名改变标签的名称

可以使用字段别名改变标签的名称

可以使用包别名改变标签的名称

通过实现SingleValueConverter接口,可以将成员字段显示到对象属性标签上