Spring OXM-XStream使用别名

来源:互联网 发布:数据库中的文件类型 编辑:程序博客网 时间:2024/04/30 04:32

  • 导读
  • 别名配置的三种情况
  • 官方Demo
    • 问题
    • Model
    • A Simple Test
    • Class aliasing
    • Field aliasing
    • Implicit Collections
    • Attribute aliasing
  • Package aliasing
  • 示例源码

导读

在Spring OXM-XStream快速入门 的案例中,我们看到生成的xml报文如下:

<com.xgj.oxm.xstream.quickDemo.domain.User>  <id>1</id>  <userName>Artisan</userName>  <password>artisan</password>  <credits>1000</credits>  <lastVisit>2017-12-05 07:30:46.772 UTC</lastVisit>  <logs>    <com.xgj.oxm.xstream.quickDemo.domain.LoginLog>      <loginLogId>99</loginLogId>      <userId>1</userId>      <ip>127.0.0.1</ip>      <loginDate>2017-12-05 07:30:46.772 UTC</loginDate>    </com.xgj.oxm.xstream.quickDemo.domain.LoginLog>  </logs></com.xgj.oxm.xstream.quickDemo.domain.User>

在默认情况下,Java对象到XML的映射是Java对象属性名对应XML的元素名,Java类的全名对应XML根元素的名字。

事实上,在实际应用中,如果XML和Java类都已经存在相应的名称,那么在进行转换时,需要设置别名进行映射。


别名配置的三种情况

  • 类别名: 使用alias(String name,Class type)

  • 类成员别名:使用aliasField(String alias, Class definedIn, String fieldName)

  • 类成员作为xml属性别名:使用aliasAttribute(Class definedIn, String attributeName, String alias)方法。 并且需要通过 useAttributeFor(Class definedIn, String fieldName) 应用到某个类上。

从上面的实例中我们看到XML元素结构不是很友好,接下来我们通过XStream提供的别名机制来修饰生成的XML元素的结构。

package com.xgj.oxm.xstream.quickDemo.aliasDemo;import java.text.ParseException;import java.util.Date;import com.thoughtworks.xstream.XStream;import com.xgj.oxm.xstream.quickDemo.domain.LoginLog;import com.xgj.oxm.xstream.quickDemo.domain.User;public class XStreamAliasDemo {    private static XStream xstream;    static {        // 创建一个Xstream实例,使用默认的XPP解析器        xstream = new XStream();        // (1)设置类别名,修改默认的全限定名的名称        xstream.alias("user", User.class);        xstream.alias("loginLog", LoginLog.class);        // (2)设置类成员别名 <id>1</id> 改为<userId>1</userId>        xstream.aliasField("userId", User.class, "id");        // (3)把LoginLog的userId属性视为xml属性,默认为xml的元素        xstream.aliasAttribute(LoginLog.class, "userId", "id");        xstream.useAttributeFor(LoginLog.class, "userId");        // (4)去掉集合类型生成XML的父节点,即忽略xml中的<logs></logs>标记        xstream.addImplicitCollection(User.class, "logs");    }    /**     *      *      * @Title: getUser     *      * @Description: 初始化转换对象     *      * @return     *      * @return: User     * @throws ParseException     */    public static User getUser() throws ParseException {        LoginLog log = new LoginLog();        log.setIp("127.0.0.1");        log.setLoginLogId(99);        log.setUserId(1);        log.setLoginDate(new Date());        LoginLog log2 = new LoginLog();        log2.setIp("192.168.1.1");        log2.setLoginLogId(22);        log2.setUserId(2);        log2.setLoginDate(new Date());        User user = new User();        user.setId(1);        user.setUserName("Artisan");        user.setPassword("artisan");        user.setCredits(1000);        user.setLastVisit(new Date());        user.addLoginLog(log);        user.addLoginLog(log2);        return user;    }    /**     *      *      * @Title: objectToXml     *      * @Description: Java对象转换成XML     *      * @throws Exception     *      * @return: void     */    public static void objectToXml() throws Exception {        // 获取转换的User对象实例        User user = getUser();        // 输出内容到控制台,查看一下        System.out.println(xstream.toXML(user));        System.out.println("objectToXml successfully");    }    public static void main(String[] args) throws Exception {        objectToXml();    }}

输出

<user>  <userId>1</userId>  <userName>Artisan</userName>  <password>artisan</password>  <credits>1000</credits>  <lastVisit>2017-12-05 13:39:32.698 UTC</lastVisit>  <loginLog id="1">    <loginLogId>99</loginLogId>    <ip>127.0.0.1</ip>    <loginDate>2017-12-05 13:39:32.698 UTC</loginDate>  </loginLog>  <loginLog id="2">    <loginLogId>22</loginLogId>    <ip>192.168.1.1</ip>    <loginDate>2017-12-05 13:39:32.698 UTC</loginDate>  </loginLog></user>

说明:

在(1)处,通过XStream的alias方法来设置类别名。

在(2)处,通过XStream的aliasField方法将User类的id属性设置为userId

在(3)处,通过XStream的aliasAttribute和useAttributeFor方法将LoginLog类的userId属性设置为id,并设置为LoginLog元素的属性。 默认为LoginLog元素的子元素。

在(4)处,通过XStream的addImplicitCollection方法删除集合节点logs,即忽略XML中的<logs></logs>标记。


官方Demo

问题

假设我们有如下的XML,我们如何使用XStream去读写呢?

<blog author="Guilherme Silveira">  <entry>    <title>first</title>    <description>My first blog entry.</description>  </entry>  <entry>    <title>tutorial</title>    <description>        Today we have developed a nice alias tutorial. Tell your friends! NOW!    </description>  </entry></blog>

结合XStream中的方法,我们来分析一下

  • blog 节点有个 author 属性 ,可以使用aliasAttribute 和 useAttributeFor方法应用到Blog类上,也可以使用XStream的转换器,这里我们使用转换器的方式。 因为要使用转换器,所以需要一个Author类以及对应的一个name属性用于存储name的值

  • 子节点是多个entry,可以使用List来存储

  • entry节点有title 和 description 属性 ,所以需要一个Entry类以及2个属性


Model

接下来我们来看下我们创建的几个model类

package com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo;import java.util.ArrayList;import java.util.List;public class Blog {    // Author    private Author writer;    // Entry集合    private List<Entry> entries = new ArrayList<Entry>();    /**     *      *      * @Title:Blog     *      * @Description:构造函数     *      * @param writer     */    public Blog(Author writer) {        this.writer = writer;    }    /**     *      *      * @Title: add     *      * @Description: 添加Entry     *      * @param entry     *      * @return: void     */    public void add(Entry entry) {        entries.add(entry);    }    /**     *      *      * @Title: getContent     *      * @Description: 获取Entry List集合     *      * @return     *      * @return: List<Entry>     */    public List<Entry> getContent() {        return entries;    }}
package com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo;public class Author {    private String name;    public Author(String name) {        this.name = name;    }    public String getName() {        return name;    }}
package com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo;public class Entry {    private String title, description;    public Entry(String title, String description) {        this.title = title;        this.description = description;    }}

我们没有创建set/get方法,可根据需要创建。


A Simple Test

接下来,我们来测试一下

public static void main(String[] args) {        Blog teamBlog = new Blog(new Author("Guilherme Silveira"));        teamBlog.add(new Entry("first","My first blog entry."));        teamBlog.add(new Entry("tutorial",                "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));        XStream xstream = new XStream();        System.out.println(xstream.toXML(teamBlog));}

输出如下

<com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Blog>  <writer>    <name>Guilherme Silveira</name>  </writer>  <entries>    <com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Entry>      <title>first</title>      <description>My first blog entry.</description>    </com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Entry>    <com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Entry>      <title>tutorial</title>      <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>    </com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Entry>  </entries></com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Blog>

Class aliasing

我们需要把com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Blog 和 com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Entry 转换成 blog 和 entry.

通过

    xstream.alias("blog", Blog.class);    xstream.alias("entry", Entry.class);
Blog teamBlog = new Blog(new Author("Guilherme Silveira"));        teamBlog.add(new Entry("first", "My first blog entry."));        teamBlog.add(new Entry("tutorial",                "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));        XStream xstream = new XStream();        // alias Class        xstream.alias("blog", Blog.class);        xstream.alias("entry", Entry.class);        System.out.println(xstream.toXML(teamBlog));

输出结果如下

<blog>  <writer>    <name>Guilherme Silveira</name>  </writer>  <entries>    <entry>      <title>first</title>      <description>My first blog entry.</description>    </entry>    <entry>      <title>tutorial</title>      <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>    </entry>  </entries></blog>

Field aliasing

下面把wirter转换为 author .通过

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

输出如下

<blog>  <author>    <name>Guilherme Silveira</name>  </author>  <entries>    <entry>      <title>first</title>      <description>My first blog entry.</description>    </entry>    <entry>      <title>tutorial</title>      <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>    </entry>  </entries></blog>

Implicit Collections

去掉entries节点,通过

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

输出如下

<blog>  <author>    <name>Guilherme Silveira</name>  </author>  <entry>    <title>first</title>    <description>My first blog entry.</description>  </entry>  <entry>    <title>tutorial</title>    <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>  </entry></blog>

Attribute aliasing

下一步是将writer成员变量转换为xml的属性 , 为了做到这一点,我们需要告诉XStream将Blog#writer字段同义为author

问题 : how does XStream converts an Author in a String so it can be written as a XML tag attribute?

Attributes cannot be written for types that are handled by Converter implementations, we have to use a SingleValueConverter and implement our own converter for the Author:

package com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo;import com.thoughtworks.xstream.converters.SingleValueConverter;public class AuthorConverter implements SingleValueConverter {    /**     * tells XStream which types it can deal with     */    public boolean canConvert(Class type) {        return type.equals(Author.class);    }    /**     * extract a String from an Author     */    public String toString(Object obj) {        return ((Author) obj).getName();    }    /**     * takes a String and returns an Author     */    public Object fromString(String name) {        return new Author(name);    }}

然后注册转换器

xstream.useAttributeFor(Blog.class, "writer");xstream.registerConverter(new AuthorConverter());

完整的代码如下

package com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo;import com.thoughtworks.xstream.XStream;public class AliasTest {    public static void main(String[] args) {        Blog teamBlog = new Blog(new Author("Guilherme Silveira"));        teamBlog.add(new Entry("first", "My first blog entry."));        teamBlog.add(new Entry("tutorial",                "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));        XStream xstream = new XStream();        xstream.alias("blog", Blog.class);        xstream.alias("entry", Entry.class);        xstream.aliasField("author", Blog.class, "writer");        xstream.addImplicitCollection(Blog.class, "entries");        xstream.useAttributeFor(Blog.class, "writer");        xstream.registerConverter(new AuthorConverter());        System.out.println(xstream.toXML(teamBlog));    }}

输出

<blog author="Guilherme Silveira">  <entry>    <title>first</title>    <description>My first blog entry.</description>  </entry>  <entry>    <title>tutorial</title>    <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>  </entry></blog>

Package aliasing

 xstream.aliasPackage("my.company", "org.thoughtworks");

比如

package com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo;import com.thoughtworks.xstream.XStream;public class AliasPackage {    public static void main(String[] args) {        Blog teamBlog = new Blog(new Author("Guilherme Silveira"));        teamBlog.add(new Entry("first", "My first blog entry."));        teamBlog.add(new Entry("tutorial",                "Today we have developed a nice alias tutorial. Tell your friends! NOW!"));        XStream xstream = new XStream();        xstream.aliasPackage("com.artisan",                "com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo");        System.out.println(xstream.toXML(teamBlog));    }}

输出

<com.artisan.Blog>  <writer>    <name>Guilherme Silveira</name>  </writer>  <entries>    <com.artisan.Entry>      <title>first</title>      <description>My first blog entry.</description>    </com.artisan.Entry>    <com.artisan.Entry>      <title>tutorial</title>      <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!</description>    </com.artisan.Entry>  </entries></com.artisan.Blog>

示例源码

代码已托管到Github—> https://github.com/yangshangwei/SpringMaster

原创粉丝点击