Spring OXM-XStream转换器

举报
小工匠 发表于 2021/09/10 23:51:48 2021/09/10
【摘要】 概述示例示例源码 概述 我们在开发的过程中,有的时候需要转换一些自定义类型,此时默认的映射方式可能无法满足需要。 XStream为我们提供了丰富的扩展,用户可以实现自己...

概述

我们在开发的过程中,有的时候需要转换一些自定义类型,此时默认的映射方式可能无法满足需要。

XStream为我们提供了丰富的扩展,用户可以实现自己的转换器,然后调用registerConverter方法注册自定义的转换器。

实现自定义的转换器很简单,只需要实现XStream提供的Converter接口并实现其方法即可。


示例

我们在上个案例中的代码

package com.xgj.oxm.xstream.quickDemo.convert;

import java.text.ParseException;
import java.util.Date;
import java.util.Locale;

import com.thoughtworks.xstream.XStream;
import com.xgj.oxm.xstream.quickDemo.domain.LoginLog;
import com.xgj.oxm.xstream.quickDemo.domain.User;

public class XStreamConverterDemo {

    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));
    }



    public static void main(String[] args) throws Exception {
        objectToXml();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

输出如下

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

可以看到时间格式如下:

2017-12-06 12:32:06.504 UTC
  
 
  • 1

UTC与格林尼治平均时(GMT, Greenwich Mean Time)一样,都与英国伦敦的本地时相同,UTC + 时区差=本地时间

如果我们希望显示北京时间呢?

就需要用到转换器了

package com.xgj.oxm.xstream.quickDemo.convert;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

public class DateConverter implements Converter {

    private Locale locale;

    public DateConverter(Locale locale) {
        super();
        this.locale = locale;
    }

    /**
     * 重写该方法,判断需要转换的类型
     */
    @Override
    public boolean canConvert(Class type) {
        return Date.class.isAssignableFrom(type);
    }

    /**
     * 重写该方法,编写Java 到 XML 的转换逻辑
     */
    @Override
    public void marshal(Object source, HierarchicalStreamWriter writer,
            MarshallingContext context) {

        // DateFormat format = DateFormat.getDateInstance(DateFormat.DATE_FIELD,
        // this.locale);

        SimpleDateFormat format = new SimpleDateFormat(
                "yyyy-MM-dd HH:mm:ss", this.locale);

        writer.setValue(format.format(source));

    }

    /**
     * 重写该方法,编写XML 到 Java 的转换逻辑
     */
    @Override
    public Object unmarshal(HierarchicalStreamReader reader,
            UnmarshallingContext context) {

        GregorianCalendar calendar = new GregorianCalendar();

        // DateFormat format = DateFormat.getDateInstance(DateFormat.DATE_FIELD,
        // this.locale);

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
                this.locale);

        try {
            calendar.setTime(format.parse(reader.getValue()));
        } catch (Exception e) {
            throw new ConversionException(e.getMessage(), e);
        }

        return calendar.getGregorianChange();
    }

}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74

解析

  • 通过 canConvert 方法来判断转换逻辑

  • 通过marshal方法,完成对象编组(对象转XML)操作的处理逻辑

  • 通过unmarshal方法,完成对象f反编组(XML转对象)操作的处理逻辑

  • 最后调用registerConverter方法注册自定义的转换器


修改生成xml的代码注册转换器,完整代码如下

package com.xgj.oxm.xstream.quickDemo.convert;

import java.text.ParseException;
import java.util.Date;
import java.util.Locale;

import com.thoughtworks.xstream.XStream;
import com.xgj.oxm.xstream.quickDemo.domain.LoginLog;
import com.xgj.oxm.xstream.quickDemo.domain.User;

public class XStreamConverterDemo {

    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");

        // 注册转换器
        xstream.registerConverter(new DateConverter(Locale.CHINESE));
    }

    /**
     * 
     * 
     * @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));
    }



    public static void main(String[] args) throws Exception {
        objectToXml();
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

输出

<user>
  <userId>1</userId>
  <userName>Artisan</userName>
  <password>artisan</password>
  <credits>1000</credits>
  <lastVisit>2017-12-06 20:34:42</lastVisit>
  <loginLog id="1">
    <loginLogId>99</loginLogId>
    <ip>127.0.0.1</ip>
    <loginDate>2017-12-06 20:34:42</loginDate>
  </loginLog>
  <loginLog id="2">
    <loginLogId>22</loginLogId>
    <ip>192.168.1.1</ip>
    <loginDate>2017-12-06 20:34:42</loginDate>
  </loginLog>
</user>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

可以看到时间已经是 2017-12-06 20:34:42 北京时间了。 转换器起作用了。


示例源码

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

文章来源: artisan.blog.csdn.net,作者:小小工匠,版权归原作者所有,如需转载,请联系作者。

原文链接:artisan.blog.csdn.net/article/details/78725702

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。