XStream 学习笔记
Posted onXStream 学习笔记
XStream
使用XStream**的初衷**
研究和使用XStream的原因是我在项目中的一个预研。在项目中需要应用到对XML文件的管理和配置,因此需要一个能够将对象保存为XML的工具库,在这里有多种方法实现,我也研究并进行了比对,比如与Zeus工具的比对,与Java自身的XML工具库的比对等。在这里,我就描述下我的XStream学习过程和研究结果。
XStream**简单介绍**
XStream是一个开源项目,一套简单实用的类库,用于序列化对象与XML对象之间的相互转换。将XML文件内容解析为一个对象或将一个对象序列化为XML文件。
XStream可以用于JDK1.3以上的版本使用,我是在JDK1.5下使用它的。
XStream的相关信息可以到http://xstream.codehaus.org/下查看,它有专门的JavaDoc,可以方便的阅读Xstream的函数及方法。
XStream中主要的类为XStream,它用于序列化对象与XML 对象之间的相互转换。简单的使用它就可以解决很多问题。
XStream中主要的方法也是我用的比较多的是fromXML()和toXML()。
fromXML用于从XML中将对象解析出来。
toXML用于将对象序列化为XML文件。
在XStream中我还使用HierarchicalStreamWriter,HierarchicalStreamReader,createObjectInputStream(),createObjectOutputStream(),主要是用于对象的输入输出。
下面我们来研究下XStream的工作方式。
XStream**的实例——将一个序列化对象转化为XML**对象。
一,创建XStream对象。
XStream xstream=new XStream();
用默认构造器构造了一个名为xstream的XStream的对象。默认构造器所使用XML解析库为Xpp3库,XPP3是一种运行效率非常高的XML全解析实现。
二,创建需要序列化的对象。
比如这个类就叫PrintUnit。
构造也比较简单,一个简单的JavaBean
public class PrintUnit
{
Private String a;
Private String b;
Private String c;
Public PrintUnit(){}
Public setA(String a)
{
this.a=a;
}
Public getA()
{
return a;
}
Public setB(String b)
{
this.b=b;
}
Public getB()
{
return b;
}
Public setC(String c)
{
This.c=c;
}
Public getC()
{
Return c;
}
}
在例子中使用这个JavaBean。
创建并初始化PrintUnit。
PrintUnit pu=new PrintUnit();
pu.setA("A11");
pu.setB("B22");
pu.setC("C33");
三,创建Writer。
创建一个输出流,至于怎么输出我发现可以使用多种方法,其实原理是一样的。
在这里就不得不提到HierarchicalStreamWriter,HierarchicalStreamWriter是一个接口,从字面上意思来说它是有等级的输入流。同样在XStream中也有不少这个接口的实现类用于输出。我现在所用过的有CompactWriter和PrettyPrintWriter这2个。
我是这样做的:
String str="stream.xml"; //本目录下的一个名为stream的XML文件
PrintWriter pw=new PrintWriter(str);//创建一个PrintWriter对象,用于输出。
之后选用一个HierarchicalStreamWriter的实现类来创建输出。
选用CompactWriter创建:
CompactWriter cw=new CompactWriter(pw);
选用PrettyPrintWriter创建:
PrettyPrintWriter ppw=new PrettyPrintWriter(pw);
两者所使用的方法都是很简单的。
CompactWriter与PrettyPrintWriter的区别在于,以CompactWriter方法输出的为连续的没有分隔的XML文件,而用PrettyPrintWriter方法输出的为有分隔有一定格式的XML文件。
以CompactWriter方式生成的XML文件:
以上步骤完成后就可以做输出操作了,XStream的输出方式有多种:toXML方式,ObjectOutputStream方式,marshal方式以及一些我尚未发现的一些其它方式。 先说下我所使用的方式它们各自的不同点,从工作原理上说它们是相似的,但是做法各不相同。 toXML()方法,本身toXML的方法就有2种: 第一种:java.lang.String toXML(java.lang.Object obj) 将对象序列化为XML格式并保存到一个String对象中。 第二种:void toXML(java.lang.Object obj, java.io.Writer out) 将对象序列化为XML格式后以Writer输出到某个地方存储。 我所使用的是第二种方式,使用前面已经做好的Pw就可以实现输出,它其实很简单不需要再去做其它定义,只需要一个PrintWriter对象和需要序列化的Object即可。 直接调用xstream.toXML(printUnit,pw);就能输出XML文件,在这里是输出到该目录下的stream.xml中。这里的输出都是覆盖性的,不是末尾添加形式。 使用ObjectOutputStream方式,简单说它就是生成一个对象输出流。 ObjectOutputStream objout = xstream.createObjectOutputStream(ppw); 使用XStream的createObjectOutputStream方法创建一个ObjectOutputStream对象,用于XML的输出。这里使用的是PrettyPrintWriter的方式。 之后调用writerObject方法既可,使用方法与其它输出流类似。 obj_out.writeObject(pu); obj_out.close(); 使用marshal方式,其实marshal方法和toXML方法是相同的。在调用toXML方法进行输出时,在XStream内部是需要调用marshal方法的,然后它再去调用对象marshallingStrategy的marshal方法。所以做toXML其实和marshal是相同的,在这里只是想更加说明它的工作方式。 使用 void marshal(java.lang.Object obj, HierarchicalStreamWriter writer)方法。 延续上面的例子,在这里可以这样写:xstream.marshal(pu,ppw); 需要注意的是,和toXML不同的是参数,一个是PrintWriter对象一个则是PrettyPrintWriter对象。因为marshal中需要 HierarchicalStreamWriter,而PrettyPrintWriter则是实现了HierarchicalStreamWriter接口的实现类。 结果和toXML是相同的。 五,结果:
w
不知道是我哪里没有处理,还是实际并不是像我想象的哪么简单,使用XMLEncoder所输出的XML文件中有一定的问题,虽然它很详细,比起XStream所生成的更多,包括了XML和Java的版本看上去更像是个完整的XML文件,不过再细看它们两生成的XML格式内容,完全不同,这个我想就是它们最大的区别。这让我想到了很多内容:工作方式,解析器,转换方式等。大家有没发现在开始和结束都存在一些乱码数据,难道在XMLEncoder输出过程中或数据转换中内容已经存在“脏”数据了?还是我所使用的输出方式存在问题?哎…一个又一个问题出现了。我想我需要再进一步的研究和学习才能得到答案。
不过尽管有这个那个的问题,使用Java本身自带的XML工具还是一样很实用的,读取和输出一样可用,操作也很灵活。因此我觉得在某些场合使用特定的工具可能会更好,利用XMLEncoder和XMLDecoder同样可以解决一些问题。
我的这个使用XMLDecoder和XMLEncoder的序列化格式输出暂研究到这里。 枫情·太子爷 2005年12月16日
发表于 2005-12-16 16:22 枫情·太子爷 阅读(3625) 评论(4) 编辑 收藏
fanta 评论于 2005-12-16 16:45 /# re: XStream 学习笔记 回复 更多评论
还有很多问题,比如:
当bean的字段为int类型,如果这个字段没有值,它默认输出是0
而实际应用中我们需要的是
呵呵.在JAVA里面,INT类型的变量本来默认值就是0,你没有给它值,它也会默认将0作为这个变量的初始值....@xmlspy2004 心无痕 评论于 2008-03-03 14:39 /# re: XStream 学习笔记 回复 更多评论
出现:Exception in thread "main" com.thoughtworks.xstream.alias.CannotResolveClassException: 的可能原因是:调用xStream.alias("PrintUnit ",PrintUnit.class) 时写错了, 尤其是第一个参数,要跟xml中的大小写一致! good Luck! jadar 评论于 2008-05-12 16:52