Commons-betwixt和Xstream组件的比较浅析

来源:互联网 发布:淘宝网鞋子批发 编辑:程序博客网 时间:2024/04/30 12:23

 

 
 

Commons-betwixtXstream比较浅析

--- by 姚亮 2005-10-13

 

 

 

 

 

 

 

 

 

 

 

 

 

 

目录

Commons-betwixtXstream比较浅析... 3

1. 原理及流程简介... 3

1.1commons-betwixt 3

1.2 Xstream.. 3

2. 举例说明... 4

2.1 用到的Java Bean信息... 4

2.2commons-betwixt解析举例... 5

2.3 Xstream解析举例... 6

3 运行环境... 7

硬件环境... 7

软件环境... 7

4 两者对比浅析... 7

4.1commons-betwixt浅析... 7

4.2 Xstream浅析... 8

4.3 对比浅析... 9

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Commons-betwixtXstream比较浅析

1. 原理及流程简介

1.1 commons-betwixt

²       基本原理

Commons Betwixt这个组件提供了一个XML自省(introspection)机制用来把Java Bean映射成XML信息(.xml文件或符合xml格式的字符串,下同)或者把XML信息映射成Java Bean

在解析XML信息时采用SAX方式。

²       核心类,方法及步骤简介

n        xml信息映射成java bean

org.apache.commons.betwixt.io.BeanReader

       要把xml信息映射成 JavaBean,这个类是最核心的类。首先要构造此类的一个对象。然后配置该对象属性,(包括给XML信息是否匹配AttributeId等等),下来最重要的一步是给这个对象注册一个BeanClass,即要转化的Java Bean的类名,函数原型为:void registerBeanClass(String path, Class beanClass),其中pathXML信息中要转化的element名。接下来就是最后一步,调用核心方法Object parse(String),这个方法不是BeanReader本身的。而是它继承的org.apache.commons.digester.Digester里面的方法,这里不在叙述。

n        java bean映射成xml信息

org.apache.commons.betwixt.io.BeanWriter

       要把Java Bean 映射成XML信息,此为核心类。同样,首先要构造此类的一个对象,然后配置该对象(包括是否给生成的XML信息设置格式化,AttributeId等等),然后调用核心方法writeString nameObject beanname是即将生成的XML信息的element名,bean为待转化的对象。此方法是BeanWriter自身的方法。

²       需要的支持环境:

commons-digester.jarcommons-beanutils.jar,commons-codec.jarcommons-lang.jardom4j-1.3.jar

1.2 Xstream

²       基本原理

Xstream这个组件也提供了一个XML自省(introspection)机制用来把Java Bean映射成XML信息或者把XML信息映射成Java Bean

不同的是在解析xml信息时采用的是DOM方式

²       核心类,方法及步骤简介

Xstream在把xml信息和java bean相互转换的过程中用到同一个应用类。

com.thoughtworks.xstream.XStream

commons-betwixt组件一样,首先需要建立一个XStream的对象,但是它少了配置一步(其实是它自己在程序里已经配置好了),下来也和commons-betwixt组件一样,最重要的一步,给这个对象注册一个BeanClass,即要转化的Java Bean的类名,函数原型为:public void alias(String name, Class type),其中namexml信息中的element名称,下来就可以调用核心方法fromXML() toXML(Object)xml信息转化成java bean或把对象转化成xml信息了。

²       需要的支持环境:

xpp3-1.1.3.4d_b4_min.jarxom-1.0b3.jarstax-api-1.0.jarjdom-1.0.jardom4j-1.3.jarcommons-lang-2.0.jarjmock-2004-03-19.jarjoda-time-1.0.jarstax-1.1.1-dev.jarxml-writer-0.2.jar

2. 举例说明

2.1 用到的Java Bean信息

为了更能体现出效果,就用com.guangyu.pmv4.model.User类来做测试之用。

²       User对象

User user = newUser();

//parment

Department dep =new Department();

dep.setId(Long.valueOf(1));

dep.setName("杭州广域");

dep.setSerialTitle("pSerialTitle");

dep.setType(newInteger(234));

user.setDepartment(dep);      

//       

user.setId(Long.valueOf(2));

 

Set grants = newHashSet();

grants.add("删除");

grants.add("添加");

grants.add("更新");

grants.add("查看");

user.setAccessGrants(grants);

user.setFirstViceCategory(newInteger(2));

user.setUserName("姚亮");

user.setUserId("luna");

user.setType(newInteger(2));

user.setStatus(newInteger(1));

user.setPassword("11111111");

user.setIpAddress("10.13.45.178");

user.setId(Long.valueOf(1));

user.setFirstViceCategory(newInteger(2));

²       Xml信息

两种方法在解析时用到的xml信息是各自在第一步由User对象转化成String时得到的,两者得到的xml信息有很大的差别,影响着各自解析的性能,在后面的分析说明里将详细说明

2.2 commons-betwixt解析举例

²       Java Bean转换成xml String

n        代码

BeanWriter writer= new BeanWriter();

writer.getXMLIntrospector().getConfiguration()

   .setAttributesForPrimitives(false);

writer.getBindingConfiguration().setMapIDs(false);

writer.enablePrettyPrint();

writer.write(user);

n        结果

  <User>

    <accessGrants>

      <accessGrant>查看</accessGrant>

      <accessGrant>添加</accessGrant>

      <accessGrant>更新</accessGrant>

      <accessGrant>删除</accessGrant>

    </accessGrants>

    <department>

      <id>1</id>

      <name>杭州广域</name>

     <serialTitle>pSerialTitle</serialTitle>

      <subDepartments/>

      <type>234</type>

      <users/>

    </department>

    <endDate/>

   <firstViceCategory>2</firstViceCategory>

    <id>1</id>

   <ipAddress>10.13.45.178</ipAddress>

    <mainCategory/>

   <password>11111111</password>

    <secondViceCategory/>

    <startDate/>

    <status>1</status>

    <type>2</type>

   <userId>luna</userId>

    <userName>姚亮</userName>

  </User>

²       xml转化成Java Bean

n        代码

BeanReaderreader = new BeanReader();

reader.getXMLIntrospector().getConfiguration()

         .setAttributesForPrimitives(false);

reader.getBindingConfiguration().setMapIDs(false);

reader.registerBeanClass(“User”,User.class);

User u = (User)reader.parse(new StringReader(value));

n        运行时间。(不包含log)

100次共耗时1328毫秒;平均运行一次耗时不到14毫秒

2.3 Xstream解析举例

²       Java Bean转化成xml 信息

n        代码如下

XStream s = newXStream();

s.alias("user",User.class);

s.alias("department",Department.class);

System.out.println(s.toXML(user));

n        结果如下

<user>

  <id>1</id>

  <status>1</status>

  <userId>luna</userId>

  <userName>姚亮</userName>

 <password>11111111</password>

  <type>2</type>

 <ipAddress>10.13.45.178</ipAddress>

  <department>

    <id>1</id>

   <name>杭州广域</name>

    <type>234</type>

   <serialTitle>pSerialTitle</serialTitle>

  </department>

  <accessGrants>

    <string>查看</string>

    <string>添加</string>

    <string>更新</string>

    <string>删除</string>

  </accessGrants>

  <firstViceCategory>2</firstViceCategory>

</user>

²       xml信息转化成Java Bean

n        代码如下

XStream s = newXStream();

s.alias("user",User.class);

User u = (User) s.fromXML(value);

n        运行时间。(不包含log

运行100次共耗时790毫秒,平均解析一次耗时7.9,不到8毫秒

3 运行环境

硬件环境

intel2.66GHZ+1048048mRAM

软件环境

1.11.2中具体的环境支持说明

4 两者对比浅析

4.1 commons-betwixt浅析

²       优点

n        方便,快速。构造相应的对象,配置好以后就可以开始xmljava Bean的转化,尤其解析xml信息时有多种参数的方法供调用,可以直接对文件进行解析。而在解析xml信息到java bean时,小于14毫秒的速度足以使之成为解析xml产品中的佼佼者。(写到这里自己先寒一个,感觉在推销产品^_^)

n        强壮。一个好的组件能被广泛流传不仅仅是因为好用,还要足够强壮,能处理一些异常的情况,比如待解析的xml信息如果包含javabean以外的标签,例如在上面的例子中,给xml信息加入<good>notgood</good>之类的java bean里没有的属性,betwixt在解析的时候会跳过这些标签,同时正确的解析其他的属性。而且如果javabean自身的属性为空,比如<userName/>,betwixt解析的时候会将相应的属性设置为null。在上面的例子中还可以把<user>…</user>全部包括在另外的标签之下,比如<relatedObject><user>…</user></relatedObject>,但是一定要在配置的时候指定解析的路径,比如:reader.registerBeanClass(“relatedObject/user”, User.class);

²       缺点

n        笨。其实betwixt是很笨的,它在解析的时候都要去找Java Bean里面的gettersetteradder函数来匹配相应的标签值。而且Java Bean还要执行了Serializable,所以解析之前,必须先在类里定义好诸如此类的方法。另外一点在一个数据结构里面只能出现同一种对象。例如一个List对象,它里面只能存放同一种对象。

n        对特殊字符的支持不够,如果在标签里面出现”<””>”bwtwixt一定会抛出异常的,例如<userName>hehe>heeh</userName>.还有其他的一些特殊字符,具体哪些支持那些不支持现在还不是很清楚。

n        解析xml的时候有好几种调用方法 ,其中有一个的参数是Stringpublic ObjectparseString,经常会出现unknownSource的异常,很怪异。到现在还不知所以然,所以建议调用它的另外一个方法 public Object parseReader

4.2 Xstream浅析

²       优点

n        如果bwtwixt用方便快速来形容的话,那Xstream只能说是,简直太方便,简直太快速了。在xml解析的产品中,如果光看方便性和速度,它一定首屈一指,可惜它却有别的瑕疵,这是后话了,先来看看它到底有多么方便吧。

Xstream在解析xml信息时,不需要配置(其实betwixt的配置也没有什么实质性的东西,事实上也是可以去掉的),不需要java bean执行Serializable,不需要gettersetteradder函数(想不明白这些都不需要,它是怎么把属性添加进去的,但是事实上它却做到了),甚至不需要注册Class(就是alias()方法,相当于betwixt里面的registerBeanCalss()方法)就可以把xml转化成你想要的对象,例如在本文的例子中,如果把xml信息的user标签由原来的<user>…</user>改成<com.guangyu.pmv4.model.user>…</com.guangyu.pmv4.model.user>,就不需要注册类了,仅仅两步就可以完成:

XStream stream =new XStream();

User user =  (User) Stream.fromXML(value);

另外,它的速度更快,解析一次不到8毫秒。傻了吧?^_^

n        对特殊字符的支持。如果在标签里面出现<username>hehe>hehe</username>的情况,它一样可以解析成功。

n        在同一种数据结构里面可以存放不同的对象。例如在一个List对象里面既可以有对象A,也可以有对象B,但是一定要注册类。例如:

String xml = “<list><a>…</a><b>…</b><list>”;

XStream stream =new XStream();

stream.alias(“list”,ArrayList.class);

stream.alias(“a”,A.class);

stream.alias(“b”,B.class);

List list =(List) stream.fromXML(xml);

这样解析后的list对象就同时有AB对象

²       缺点

n        不够强壮。这也许成为了Xstream的致命弱点。Xstream在解析的时候碰到诸如<userName/>的标签,它不会简单得跳过,而是用一个空的字符串””去设置匹配相应的参数,所以往往会出错,而如果这个属性是IntegerLong之类的属性,它就一定会出错,并抛出异常。Xml信息里更不能有javabean属性以外的标签出现,它也不支持把整个xml信息包含在一个大的element里,象<relatedObject><user>…</user><relatedObject>它也是一定会抛异常的。

n        一个不是缺点的缺点,但是一时的疏忽可能会造成程序运行时出错.例如,如果在要转化的javaBean里面有一个List属性的字段,解析的时候Xstream会使用默认的ArrayList,而如果你的程序里的setter方法用的是一个LinkedList结构(Xstream不会去看你的setter方法),那在使用解析后的对象时就可能出错。解决的办法是在定义这个字段的时候最好就声明它到底是哪一个结构,或者初始化,下面两种方法均可以解决这个问题。

例如:private LinkedList xxx;或者 private List xxx = new LinkedList();

4.3 对比浅析

²       把对象转化成xml信息的时候,两种方法最大的区别就是:如果某个字段为nullbetwixt会解析成<xxx/>,Xstream根本不做处理,也就是说转化后的xml信息里面就没有这个标签。看上面的示例就可以体会到。

²       在把xml解析成java bean的时候,注册类的思路不同。Betwixt注册的是一个绝对路径,而Xstream注册的是一个相对路径。例如:

registerBeanClass(“relatedObject/user”,User.class);(betwixt)

alias(“user”,User.calss)(Xstream)

²       Xstream更方便,更快速,betwixt在这方面稍逊一筹,但是也很方便,快速。

²       Betwixt更强壮。这是由betwixt的映射机制决定的,betwixt是根据类里面的gettersetteradder方法去匹配相应的属性的。而这一点也决定了它的稳定性。而Xstream在这方面就差了很多。

²       底层原理不同,betwixt使用的是SAX原理,Xstream使用的是DOM原理,而这个属性就决定了两个组件的不同命运,性能也会受到底层的影响。比如Xstream就不适合处理很大信息的情况。而这个就是由DOM自身的特性决定的。

²       另外还要说明一点,这些天忙的事情也比较多,没有好好的研究Xstream,可能有的地方我的理解存在着问题。所以希望抱着批判的态度看待这篇报告。^_^

原创粉丝点击