转载:http://www.blogjava.net/zlkn2005/archive/2005/12/16/24240.html
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文件:
<object-stream><PrintUnit><a>A11</a><b>B22</b><c>C33</c></PrintUnit></object-stream>
以PrettyPrintWriter方式生成的XML文件:
<object-stream>
<PrintUnit>
<a>A11</a>
<b>B22</b>
<c>C33</c>
</PrintUnit>
</object-stream>
我想大家能很容易的分辨出它们的差异。
四,输出操作
以上步骤完成后就可以做输出操作了,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 obj_out = 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是相同的。
五,结果:
<object-stream>
<PrintUnit>
<a>A11</a>
<b>B22</b>
<c>C33</c>
</PrintUnit>
</object-stream>
经过以上5步的操作既可将一个序列化对象转化为XML对象。
XStream的实例——将XML文件转化为一个对象
通过上面的一个例子不难看出XStream简便性,既然有了输出就一定会有输入。
输入方我们将会使用ObjectInputStream。
与输出相同我们需要有一个XStream对象,暂且名为xstream。之后需要读取的XML文件地址目录信息。沿用上面的例子。
String inputStr="xstream.xml";
XStream xstream=new XStream();
我们需要通过对象流进行输入操作,所以需要FileReader和BufferedReader。
FileReader fr=new FileReader(inputStr);
BufferedReader br=new BufferedReader(fr);
创建对象输入流
ObjectInputStream obj_input=xstream.createObjectInputStream(br);
创建对象,还是使用PrintUnit这个对象。
PrintUnit pu2;
通过ObjectInputStream中的readObject()方法将对象从XML文件中读取出来。
pu2=(PrintUnit)obj_input.readObject();
获取值:
System.out.println(pu2.getB());
控制台:
B22
从整个输入的过程来看,是一个文件的读取,将其中的对象数据取出来,然后再对这个对象数据进行操作。内容也比较简单通过ObjectInputStream输入对象。
通过以上的输入输出例子,我想大家应该很容易就能理解XStream是如何实现的。
FomXML
上面使用的是以ObjectInputStream的方式进行XML与对象之间进行转换的。下面我将使用XStream中的fromXML()方法进行转换。
首先在使用fromXML我发现一个问题,它必须使用正确的解析方式或输出方式对应的输入方式才可以正常解析读取文件,这个问题有点怪,不过确实存在,当我使用前面ObjectOutputStream方式输出的XML文件,用fromXML()解析读取时,它会报错。
错误信息:
Exception in thread "main" com.thoughtworks.xstream.alias.CannotResolveClassException: object$stream : object$stream
信息内容为:不能解析这个文件。我认为它和输出方式有关,因为上面例子中使用的是ObjectOutputStream,当我反过来做了一个实验后也证明了这一点。
实验大致内容:使用toXML()方法输出XML文件,使用ObjectInputStream解析,发现会在读取的时候抛出CannotResolveClassException异常。
错误信息:
Exception in thread "main" com.thoughtworks.xstream.alias.CannotResolveClassException:
a : a
因此我认为在解析文件的时候必须先要确定这个文件是由什么方式生成的,然后在解析它,对于使用Dom,Dom4j,XPP等不同方式解析尚未尝试。以上测试是在默认的基础上实验的,默认为XPP3的解析器。
使用fromXML的方法。
public java.lang.Object fromXML(java.lang.String xml)
public java.lang.Object fromXML(java.io.Reader xml)
public java.lang.Object fromXML(java.lang.String xml,java.lang.Object root)
public java.lang.Object fromXML(java.io.Reader xml,java.lang.Object root)
例子:
PrintUnit puTwo=(PrintUnit)xstream.fromXML(xml);
这里的xml必须是使用toXML()生成出来的。对于Reader没有太多的要求。
XStream与Java.Bean中XML工具的比较
XStream主要作用是将序列化的对象转化为一个XML文件或将XML文件解析为一个对象。当然并非只有它可以做到,很多其它工具一样可以,在Java中存在这样两个类XMLDecoder和XMLEncoder,它们是在Java.Bean包下的,它们的作用是将JavaBean转化为XML或将XML文件转化为一个Java Bean。
XMLDecoder是通过一个输入流将对象从输入流中取出并转化为一个实例的方法。它所需要的就是一个输入流及一个转化过程。
XMLDecoder的实例:
String fileStr=”xstream.xml”;//XML文件,在本目录下,延用上次使用文件。
ObjectInputStream in=new ObjectInputStream(new FileInputStream(fileStr));//创建一个ObjectInputStream用于输入。
XMLDecoder xmld=new XMLDecoder(in);//创建一个XMLDecoder对象。
延用前面所使用PrintUnit这个Bean。
PrintUnit pu=(PrintUnit)xmld.readObject();//通过XMLDecoder中的readObject方法获得PrintUnit对象。
如果获取到了这个对象那么pu中将有它的值a=A11,b=B22,c=C33。整个过程最好放try
…catch中去,能够捕获一些如:文件不存在等异常。
从操作方式上看XMLDecoder似乎不比XStream差多少,同样是可以通过ObjectInputStream获取XML文件中的对象。它们的差异就是解析的方式不同,XMLDecoder是使用Java自带的XML解析方式,而XStream则是可以自定义的,它可以使用多中方式进行解析。这些是我个人所发现的一些不同点。
XMLEncoder是通过一个输出流将对象序列化并输出为XML文件。它所需要的是一个输出流及一个输出方式。
XMLEncoder的实例:
String fileStr=”xstream.xml”;//定义一个输入的目标文件。
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(fileStr));//创建一个对象输出流。
XMLEncoder xmle=new XMLEncoder(out);//创建一个XMLEncoder对象。
延用前面所使用PrintUnit这个Bean。
//创建并初始化PrintUnit对象。
PrintUnit pu=new PrintUnit();
pu.setA(“AAA”);
pu.setB(“BBB”);
pu.setC(“CCC”);
xmle.writeObject(pu);//使用XMLEncode的writeObject方法输出pu
xmle.flush();//刷新
xmle.close();//关闭输出流
从上面的代码不难看出,使用XMLEncode方式将对象序列化并输出也是很方便的,简单调用writeObject方法能将普通Bean输出为XML文件。
XML文件的内容:
�_ <?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0" class="java.beans.XMLDecoder">
<object class="test.PrintUnit">
<void property="a">
<string>AAA</string>
</void>
<void property="b">
<string>BBB</string>
</void>
<void property="c">
<string>CCC</string>
</void>
</object>
w </java>
不知道是我哪里没有处理,还是实际并不是像我想象的哪么简单,使用XMLEncoder所输出的XML文件中有一定的问题,虽然它很详细,比起XStream所生成的更多,包括了XML和Java的版本看上去更像是个完整的XML文件,不过再细看它们两生成的XML格式内容,完全不同,这个我想就是它们最大的区别。这让我想到了很多内容:工作方式,解析器,转换方式等。大家有没发现在开始和结束都存在一些乱码数据,难道在XMLEncoder输出过程中或数据转换中内容已经存在“脏”数据了?还是我所使用的输出方式存在问题?哎…一个又一个问题出现了。我想我需要再进一步的研究和学习才能得到答案。
不过尽管有这个那个的问题,使用Java本身自带的XML工具还是一样很实用的,读取和输出一样可用,操作也很灵活。因此我觉得在某些场合使用特定的工具可能会更好,利用XMLEncoder和XMLDecoder同样可以解决一些问题。
我的这个使用XMLDecoder和XMLEncoder的序列化格式输出暂研究到这里。
分享到:
相关推荐
《xStream完美转换XML、JSON》学习笔记 在IT领域,数据交换是常见的需求,而XML和JSON作为两种广泛使用的数据格式,它们之间的转换尤为重要。xStream是一个强大的Java库,它能够轻松地将Java对象序列化为XML或反...
XStream 是一个强大的 Java 库,它允许程序员将 Java 对象序列化为 XML,反之...在阅读“xstream学习文档”时,建议重点理解其核心概念、使用示例以及自定义转换器的编写,以便在实际工作中游刃有余地应对各种需求。
最齐全的xstream1.4.8.jar 最齐全的xstream1.4.8.jar 最齐全的xstream1.4.8.jar 最齐全的xstream1.4.8.jar 最齐全的xstream1.4.8.jar 最齐全的xstream1.4.8.jar 最齐全的xstream1.4.8.jar 最齐全的xstream1.4.8.jar ...
XStream 反序列化漏洞(CVE-2020-26258 & 26259),修复jar包 xstream-1.4.15.jar Xstream 是 Java 类库,用来将对象序列化成 XML (JSON) 或反序列化为对象。XStream 是一款开源软件,允许在 BSD 许可证的许可下分发...
xstream最新版jar包
《XStream详解与应用》 XStream是一款强大的Java库,用于将对象序列化为XML,同时也能从XML数据中反序列化回对象。在标题"xstream-1.4.2.jar"中,我们看到的是XStream的一个特定版本——1.4.2。这个版本包含了...
这篇博客文章,标题为“xStream学习xml,JASON,JAVA对象转换”,显然会探讨如何利用XStream来处理这两种数据格式。 XStream的核心功能在于其简单易用的API,可以将Java对象直接序列化成XML或JSON字符串,同时也能...
**XStream 概述** XStream 是一个 Java 库,用于将对象序列化为 XML,以及从 XML 反序列化回对象。它提供了一种简单而直观的...通过深入学习和实践,我们可以充分利用 XStream 的优点,提高代码的可读性和可维护性。
XStream 是一个流行的 Java 库,用于将对象序列化为 XML 和从 XML 反序列化回对象。这个库广泛应用于各种 Java 应用程序,尤其是那些需要在网络间传输或存储对象数据的情况。在标题提到的 "xstream1.4.15.JAR" 文件...
XStream库提供了一个简单、直观的方式来实现这种转换,使得XML序列化和反序列化变得非常方便。本篇将详细介绍XStream如何处理XML与Java对象的相互转换,以及如何处理List、Map等集合类型的数据。 首先,XStream是一...
xstream xstream-1.4.5.jar
XStream是一款强大的Java库,用于将Java对象序列化为XML,反之亦然。这个库的主要优点在于其简单易用的API和对复杂对象图的处理能力。在标题中提到的"Xstream相关的jar包",是指为了使用XStream库,需要引入的依赖...
《XStream 1.3.1:Java对象到XML的高效转换工具》 XStream是一款强大的Java库,它能够将Java对象序列化为XML,并能从XML反序列化回Java对象。这个“xstream-1.3.1.zip”文件包含了一个名为“xstream-1.3.1.jar”的...
《XStream解析依赖包详解》 在Java开发中,数据序列化是一个不可或缺的环节,它使得对象的状态可以被保存和恢复。XStream是一款强大的Java库,用于将Java对象转换为XML,反之亦然,极大地简化了序列化和反序列化的...
当需要将数据转换为XML格式以便于传输或处理时,工具如xStream就显得尤为重要。Java中的xStream库提供了一个简单易用的方式来将Java对象序列化为XML,反之亦然,即反序列化XML回Java对象。 **xStream简介** xStream...
XStream是一款强大的Java库,主要用于将Java对象序列化为XML,以及将XML反序列化回Java对象。在Java开发中,这种能力对于数据持久化、网络传输或配置存储等场景非常有用。标题中的"xstream-1.4.8最齐全的jar包"表明...
赠送jar包:xstream-1.4.11.jar; 赠送原API文档:xstream-1.4.11-javadoc.jar; 赠送源代码:xstream-1.4.11-sources.jar; 赠送Maven依赖信息文件:xstream-1.4.11.pom; 包含翻译后的API文档:xstream-1.4.11-...
xstream-1.4.20.jar
xstream-1.4.19.jar
**XStream简介** XStream是一款强大的Java库,用于将Java对象序列化为XML,反之亦然。它由Joe Walnes创建,提供了一种简洁而直观的方式来处理对象与XML之间的转换。XStream的核心理念是通过简单的API,使得XML绑定...