前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Spring OXM-XStream使用别名

Spring OXM-XStream使用别名

作者头像
小小工匠
发布2021-08-17 10:31:17
发布2021-08-17 10:31:17
54800
代码可运行
举报
文章被收录于专栏:小工匠聊架构小工匠聊架构
运行总次数:0
代码可运行

导读

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

代码语言:javascript
代码运行次数:0
运行
复制
<com.xgj.oxm.xstream.quickDemo.domain.User>
  1
  Artisan
  artisan
  1000
  2017-12-05 07:30:46.772 UTC
  
    <com.xgj.oxm.xstream.quickDemo.domain.LoginLog>
      99
      1
      127.0.0.1
      2017-12-05 07:30:46.772 UTC
    com.xgj.oxm.xstream.quickDemo.domain.LoginLog>
  
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元素的结构。

代码语言:javascript
代码运行次数:0
运行
复制
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)设置类成员别名 1 改为1
        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中的标记
        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();
    }

}

输出

代码语言:javascript
代码运行次数:0
运行
复制
<user>
  <userId>1userId>
  <userName>ArtisanuserName>
  <password>artisanpassword>
  <credits>1000credits>
  <lastVisit>2017-12-05 13:39:32.698 UTClastVisit>
  <loginLog id="1">
    <loginLogId>99loginLogId>
    <ip>127.0.0.1ip>
    <loginDate>2017-12-05 13:39:32.698 UTCloginDate>
  loginLog>
  <loginLog id="2">
    <loginLogId>22loginLogId>
    <ip>192.168.1.1ip>
    <loginDate>2017-12-05 13:39:32.698 UTCloginDate>
  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中的标记。


官方Demo

问题

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

代码语言:javascript
代码运行次数:0
运行
复制
<blog author="Guilherme Silveira">
  <entry>
    <title>firsttitle>
    <description>My first blog entry.description>
  entry>
  <entry>
    <title>tutorialtitle>
    <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类

代码语言:javascript
代码运行次数:0
运行
复制
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 entries = new ArrayList();

    /**
     * 
     * 
     * @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
     */
    public List getContent() {
        return entries;
    }
}
代码语言:javascript
代码运行次数:0
运行
复制
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;
    }
}
代码语言:javascript
代码运行次数:0
运行
复制
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

接下来,我们来测试一下

代码语言:javascript
代码运行次数:0
运行
复制
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));

}

输出如下

代码语言:javascript
代码运行次数:0
运行
复制
<com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Blog>
  
    Guilherme Silveira
  
  
    <com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Entry>
      first
      My first blog entry.
    com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Entry>
    <com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Entry>
      tutorial
      Today we have developed a nice alias tutorial. Tell your friends! NOW!
    com.xgj.oxm.xstream.quickDemo.aliasDemo.officeDemo.Entry>
  
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.

通过

代码语言:javascript
代码运行次数:0
运行
复制
    xstream.alias("blog", Blog.class);
    xstream.alias("entry", Entry.class);
代码语言:javascript
代码运行次数:0
运行
复制
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));

输出结果如下

代码语言:javascript
代码运行次数:0
运行
复制
<blog>
  <writer>
    <name>Guilherme Silveiraname>
  writer>
  <entries>
    <entry>
      <title>firsttitle>
      <description>My first blog entry.description>
    entry>
    <entry>
      <title>tutorialtitle>
      <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!description>
    entry>
  entries>
blog>

Field aliasing

下面把wirter转换为 author .通过

代码语言:javascript
代码运行次数:0
运行
复制
xstream.aliasField("author", Blog.class, "writer");

输出如下

代码语言:javascript
代码运行次数:0
运行
复制
<blog>
  <author>
    <name>Guilherme Silveiraname>
  author>
  <entries>
    <entry>
      <title>firsttitle>
      <description>My first blog entry.description>
    entry>
    <entry>
      <title>tutorialtitle>
      <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!description>
    entry>
  entries>
blog>

Implicit Collections

去掉entries节点,通过

代码语言:javascript
代码运行次数:0
运行
复制
xstream.addImplicitCollection(Blog.class, "entries");

输出如下

代码语言:javascript
代码运行次数:0
运行
复制
<blog>
  <author>
    <name>Guilherme Silveiraname>
  author>
  <entry>
    <title>firsttitle>
    <description>My first blog entry.description>
  entry>
  <entry>
    <title>tutorialtitle>
    <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:

代码语言:javascript
代码运行次数:0
运行
复制
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);
    }
}

然后注册转换器

代码语言:javascript
代码运行次数:0
运行
复制
xstream.useAttributeFor(Blog.class, "writer");
xstream.registerConverter(new AuthorConverter());

完整的代码如下

代码语言:javascript
代码运行次数:0
运行
复制
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));
    }
}

输出

代码语言:javascript
代码运行次数:0
运行
复制
<blog author="Guilherme Silveira">
  <entry>
    <title>firsttitle>
    <description>My first blog entry.description>
  entry>
  <entry>
    <title>tutorialtitle>
    <description>Today we have developed a nice alias tutorial. Tell your friends! NOW!description>
  entry>
blog>

Package aliasing

代码语言:javascript
代码运行次数:0
运行
复制
 xstream.aliasPackage("my.company", "org.thoughtworks");

比如

代码语言:javascript
代码运行次数:0
运行
复制
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));

    }

}

输出

代码语言:javascript
代码运行次数:0
运行
复制
<com.artisan.Blog>
  <writer>
    <name>Guilherme Silveiraname>
  writer>
  <entries>
    <com.artisan.Entry>
      <title>firsttitle>
      <description>My first blog entry.description>
    com.artisan.Entry>
    <com.artisan.Entry>
      <title>tutorialtitle>
      <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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017/12/05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导读
  • 别名配置的三种情况
  • 官方Demo
    • 问题
    • Model
    • A Simple Test
    • Class aliasing
    • Field aliasing
    • Implicit Collections
    • Attribute aliasing
  • Package aliasing
  • 示例源码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档