• 概述
  • 示例
  • 示例源码

概述

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

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

输出如下

<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>

可以看到时间格式如下:

2017-12-06 12:32:06.504 UTC

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;}/*** 重写该方法,判断需要转换的类型*/@Overridepublic boolean canConvert(Class type) {return Date.class.isAssignableFrom(type);}/*** 重写该方法,编写Java 到 XML 的转换逻辑*/@Overridepublic 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 的转换逻辑*/@Overridepublic 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();}}

解析

  • 通过 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();}
}

输出

<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>

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


示例源码

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

Spring OXM-XStream转换器相关推荐

  1. Spring OXM

    Spring OXM简介 O/X Mapping 是什么? Spring 3.0 的一个新特性是 O/X Mapper.然而O/X Mapping并不是新鲜的事物,Spring也是调用了第三方的O/X ...

  2. Spring oxm入门实例

    O/XMapper是什么? Spring3.0的一个新特性是O/XMapper.O/X映射器这个概念并不新鲜,O代表Object,X代表XML.它的目的是在Java对象(几乎总是一个plainoldJ ...

  3. spring+oxm(castor)

    1.所需jar包 castor-core-1.3.1 castor-xml-1.3.1 spring-oxm-4.0.9.RELEASE 2.实体类 package com.xwj.Xstream;i ...

  4. 【Spring】Spring oxm 入门初尝试

    O/X Mapper 是什么? Spring 3.0 的一个新特性是 O/X Mapper.O/X 映射器这个概念并不新鲜,O 代表 Object,X 代表 XML.它的目的是在 Java 对象(几乎 ...

  5. Spring OXM使用体验

    本文转载自http://www.ibm.com/developerworks/cn/xml/x-springXOM/ O/X Mapper 是什么? Spring 3.0 的一个新特性是 O/X Ma ...

  6. Spring MVC 数据类型转换器

    Spring MVC默认数据类型转换器: ConversionService converters =java.lang.Boolean -> java.lang.String : org.sp ...

  7. Spring oxm 入门

    oxm : 是spring 3.0的一个新特性 o/xMapping 什么是o/xMapping?             o/x mapping 入门:                     功能 ...

  8. XStream转换器: 处理xml节点中既有属性又有值

    1.需处理的数据: <orderInfo orderName="酸奶" orderType="奶制品" orderPrice="5.00&quo ...

  9. Spring 之 Converter转换器

    Converter主要使用于将前端数据转换为java对应的对象.比如把前端传入的字符串转换为Date类型数据 使用方法 @Component public class StringToDateConv ...

  10. java spring mvc中类转换器

    相关文章: AOP的相关的文章介绍: javaweb中Aop(jdk动态代理)https://blog.csdn.net/weixin_43319279/article/details/1031250 ...

最新文章

  1. 支付接口教程,详解支付宝接口(二)
  2. 算法:正则表达式匹配
  3. ES6新特性之函数优化-箭头函数
  4. ECMA6--字符串/数组
  5. html中radio,checkbox值的获取、赋值、注册事件
  6. Newbe.ObjectVisitor 0.4.4 发布,模型验证器上线
  7. python编辑器_没有人比它更懂少儿编程,慧编程Python'吮指编辑器'
  8. 经典排序算法(九)--鸡尾酒排序Cocktail Sort
  9. android 程序 架构,Android应用架构
  10. 由于应用程序配置不正确
  11. L2-004 这是二叉搜索树吗? (25分)*
  12. Word 批量转 PDF脚本
  13. linux gzip 加密,gzip命令
  14. Nginx代理高德API
  15. vim:修改vim录制的宏
  16. 申请专利时要不要向专利局出示实物?
  17. VC知识库的一篇文章
  18. opencv 轮廓放大_【走进OpenCV】这样腐蚀下来让我膨胀!
  19. 复旦大学计算机专硕学制几年,复旦大学硕士研究生学制是几年
  20. Unity 和 Android Studio的SDK接入(新手心得)

热门文章

  1. 监听对象中某一项的值_Vue中watch的详细用法
  2. Visual C++6.0安装教程(win10版)及“应用程序无法正常启动(0x0150002)”解决办法
  3. c++ 新建一个数组
  4. C++二进制文件读写操作
  5. python 将txt 表格转化为excel
  6. g460 bios 白名单_深睛高清车牌识别相机白名单,智能管理车辆进出_深睛车牌识别...
  7. Leetcode(20210412-20210418 第一周 每日一题)
  8. 深度5万字好文:Python应用实战案例-带你深入理解Matplotlib
  9. 产品运营必须知道的几个概念,如何进行网页分析?
  10. 判断字符串 正则_(重学前端 - JavaScript(模块一)) 14、引用类型之 RegExp (正则)(详述)...