1、简单的转换器:首先创建示例的环境,
下面介绍的是最基础的转换器,首先创建一个Person类:
接着,我们创建一个实例,并转化他:
Guilherme
到此,我们已经建立好一个可以供我们实验的基础例子了,下面我们来看看XStream的转换器能为我们做些什么:
2,创建一个Person转换器:
下面我们来创建一个简单的转换器,它能:
1,用来转换Person类
2,将Person实例转换成XML
3,将xml转换为Person实例
首先创建一个PersonConverter类,并让这个类实现Converter接口:
下面,我们首先告诉转换器,我们只能转换Person类,而不是别的类,包括其子类:
public boolean canConvert(Class clazz) {
return clazz.equals(Person.class);
}这一步很简单,除非你是用来处理泛型的转换器是会困难一点。
Marshal方法是用来将对象转换为XML的,他有三个参数:
1,我们准备转换的对象
2,我们准备输出对象的writer
3,当前的marshaling context
首先我们将object转换成Person
Person person = (Person) value;
接着,我们就可以开始输出数据了,首先我们创建一个叫做fullname的节点,并将person的名字传给他:
我们可以任意次数的调用start/end node方法,但需要记住,你必须在打开一个节点之后记住关闭它。一般来说,执行转换的操作在setValue方法调用时发生。
下面,我们进入unmarshal方法,我们使用moveDown和moveUp方法在节点树层次中移动,所以,这里我们只需要简单的moveDown,得到值,再moveUp:
最后,我们得到了一个这样的转换器:
接着,我们在我们的main方法中注册这个转化器:
注意到我们怎么注册我们的转换器了么?只需要下面简单的一句:
xStream.registerConverter(new PersonConverter());
最终得到的结果是:
Guilherme
也许你会说:这只改变了我输出的树,我需要用它来转换数据。
下面我们来尝试在person标签中创建一个叫做fullname的属性,而不是新创建一个节点:
3,一种可选的方式:
首先,为Person创建一个toString方法,里面包含了所有能用来重新创建一个Person实例的数据:
现在,我们就能把我们的转化器简写为:
现在,输出的XML也会变得更易读(为person创建别名person之后):
Guilherme 名字变成了一个内置的值,而不是一个单独的节点。
4,转换Date:
我们已经知道Converter接口是怎样工作的了,现在我们来创建一个使用Locale对象转换时间的转换器:
在我们的转换器构造方法中,我们将传入一个Locale对象,该Locale对象会作为一个成员属性被转换器持有:
现在,让我们能转换任何继承了Calendar对象的类:
首先,我们来将Calendar转换成本地化的字符串:首先我们把object转化成Calendar,得到Date对象,并使用DataFormatter来得到一个本地化的时间:
另一方面,在unmarshall方法中,我们创建了一个GregorianCalendar,得到本地化的DataFormat实例,将字符串转换成Date对象,并赋值给GregorianCalendar。
注意:
1,记住一些DataFormat实现不是线程安全的,所以,不要让你的转换器持有DataFormat的引用
2,在经过了保存和加载的过程后,该转换器可以将其他Calendar实现转换为GregorianCalendar。如果这不是你希望的,只需要修改canConvert方法,并在类型只有为GregorianCalendar的时候再返回true。
现在,我们得到了下面这个转换器:
现在,我们来测试一下,创建一个main方法:
1,创建一个calendar,
2,创建XStream对象
3,注册该转换器,并使用Brazilian Portuguese本地化对象
4,将对象转化成XML
代码如下:
可以得到类似如下的结果:
Sexta-feira, 10 de Fevereiro de 2006 注意,我们没有为GregorianCalendar创建任何别名,而gregorian-calendar就是默认的名字。
下面我们来试试unmarshal 方法:
// loads the calendar from the string
Calendar loaded = (Calendar) xStream
.fromXML("
Sexta-feira, 10 de Fevereiro de 2006");
然后打印出该日期:
// prints using the system defined locale
System.out.println(DateFormat.getDateInstance(DateFormat.SHORT).format(
loaded.getTime()));
得到的结果为:
2/10/06
5,复杂的转换器:
创建另一个例子:
我们已经创建了两个对象了,现在把它们组合起来:
要转换该类,XStream一点问题都没有。这里,我们实现自己的转换器主要是为了验证,在这里,我们想重用我们刚才的PersonConverter和CalendarConverter。canConvert仍然很简单,不过这里,我们不需要再为每一个属性重新写转换方法了,我们只需要使用已经注册了的转换器来完成转换:
如果birthday实例能够确保不会出现null值,那么我们就可以去掉marshal和unmarshal方法中对null情况的判断,也不需要循环,而直接根据tag的名字进行解析: