网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  zeus实现xml-java的数据绑定     
  文章作者:未知  文章来源:水木森林  
  查看:74次  录入:管理员--2007-11-17  
 
内容:

zeus 简介
预备知识
编译你的zeus
生成描述xml的java对象
marshal与unmarshal--xml与java object的转换
选择zeus的理由与思考
参考资料
关于作者

钟家豪 (judson78@yahoo.com.cn)

zeus可以将java对象与xml文件进行绑定,绑定使数据在j2ee中的应用更加方便。本文主要介绍zeus的编译与使用。对绑定过程中使用的dtd和xml文件也有说明。
1 zeus简介
enhydra是以生长于美国加利福尼亚海边的小水獭命名的非营利组织的名字。从但与著名的apache不同,enhydra致力于围绕application server的电子商务解决方案的研究。zeus就是enhydra开发的众多的工具软件中的一个,功能是对javaobject和xml进行数据绑定。它可以将任意的xml文件转化为对应的javaobject文件,并且将数据方便的在这两种形式之间转换。zeus最新版本是zeus1.0 beta 3.5,由于是完全的源码开放,可以到 http://zeus.enhydra.org/software/downloads/index.html 下载源代码后自己编译。

2 预备知识

2.1 用xml作为数据载体
xml(extensible markup language)由w3c组织制定并得到世界上几乎所有大公司的支持。xml是一种非常灵活的文本格式,与html相比,xml延续了其简单、易懂的语法,但是却有了更大的灵活性和扩展能力。例1是一段描述customer信息的xml文件,作为描述数据的语言,xml的组织形式很自由且表述清晰。

<?xml version="1.0" encoding="gbk"?>
<customer customer_no= "00001">
< name>李俊</ name>
<id_no>210106421016001</id_no>
<sex >男</sex>
<birth_place>大连</birth_place>
<birth_date>1942-10-16</birth_date>
<nationality>中国</nationality>
<education>高中</education>
<address>大连市沙河口</address>
<contact_info id = "00001">
<zip_code>116001</zip_code>
<tel_no>2645677</tel_no>
</contact_info>
</customer>

例1:描述customer的xml文件

这段xml结构很清晰:描述的是一个"顾客"实体,这个实体有其属性:姓名、身份证号、性别、出生地、生日、出生地、联系方式(邮编、电话)等。

第一行<?xml version="1.0" encoding="gbk"?>表述此xml文件的版本是1.0,用的是"gbk"的编码方式(如果要解析中文,gbk或gb2312是必须的)。<customer customer_no= "00001></customer>组成该文件完整的"根标记",customer_no是customer标记的"属性",<name></name>、<nationality></nationality>是<customer>的子标记。而在< contact></contact>中还可以继续包含子标记:<zip_code>、<tel_no>。用户自定义tag的xml语言给了用户足够的自由度表示数据,但是也为显示和解析带来了难度,为了解决这一问题,w3c在格式控制和标记定义上对xml加以限制。例如<customer></customer>就是一对不合格的标记。

2.2 dtd定义数据
dtd(document type definition)目的是定义xml文档中的元素和各元素间的关系。dtd可以与应用它的xml共存在一个文件中,也可以单独成为一个文件。例2是一个描述例1所述的xml文件的dtd文件。

<?xml version="1.0" encoding="gbk"?>
<!element customer (name?,id_no?,sex?,birth_place?,birth_date?,nationality?, education?, contact_info?>
<!attlist customer
customer_no cdata #required
>
<!element name (#pcdata)>
<!element id_no (#pcdata)>
<!element sex (#pcdata)>
<!element birth_place (#pcdata)>
<!element birth_date (#pcdata)>
<!element nationality (#pcdata)>
<!element education (#pcdata)>
<!element contact_info (zip_code?,tel_no?)>
<!attlist contact_info
id cdata #required
>
<!element zip_code (#pcdata)>
<!element tel_no (#pcdata)>

例2:dtd文件

无规矩不成方圆,例2的dtd文件定义了例1的xml描述的customer元素,通过dtd的定义,xml中的标记都被赋予了意义,并且很好的解释了customer与其它元素之间的关系。dtd文件的存在使xml中的数据有了规定的形式,二者由如此紧密地联系容易联想到另外一种重要的数据组织方式--数据库的表中的字段和数据。dtd-xml这种与表结构-数据类似的结构为这两种技术的相互转换提供了天然的方便条件,借助于dtd,可以方便的将表中的数据用xml表示。

3 编译你的zeus
下载下来的zeus是一个zip文件,如果选择的是源代码下载,就必须首先编译才能够使用。本文介绍zeus的使用,首先从源代码的编译说起。

编译的方法在下载的docs文件夹中有详尽的描述,作为java技术阵营的一份子,zeus在将自己完全奉献的同时也使用了其他的一些杰出的java工具。比如编译就使用了apache的ant。可以在zeuslib下找到ant.jar文件。

在编译之前唯一要做的事就是设定好操作系统的java_home环境变量。例如在windows系统,如果jdk安装在d:/jdk1.3.1,则运行set java_home = d:/jdk1.3.1。完成了准备工作就可以开始编译zeus,ant本身是易于使用的编译工具,build.xml文件可以设定所有编译的细节和文件的组装。zeus的编译文件位于根目录下的build.xml,这个xml文件包含了对zeus编译并组装zeus.jar文件的一切细节而且有很高的可读性。

确定在zeus的根目录下,运行./bin/build.bat targets,ant可以找到位于当前目录下的build.xml文件,如果不输入任何参数,ant会输出提示要你输入编译targets:

compile:编译zeus的所有源代码,并将之放置于buildclasses下;
bin:将原srcin下的文件拷到buildin下,原lib目录下的jar文件拷到buildlib下并将组合好的zeus.jar置于此文件夹下;
doc:编译javadoc,并将结果拷到bindocsapidoc下。

sample和test分别用于编译例程和测试代码。如果不想一步一步编译,可以将targers参数设为all,这样ant就会以正确的次序为你自动编译好所有的targets。编译后的会出现一个build文件夹,所有编译好的文件都在这个文件中。检查build/bin文件夹,出现的zeus.jar文件就是编译好的工具。如果你有足够的经验去修改zeus的源代码和build.xml文件,完全可以打造属于你自己的zeus。

4 生成描述xml的java对象
生成java对象的第一步是使用zeus自动生成java源代码。使用zeus的批处理文件在buildin的zeus.bat,使用语法如下:

zeus.bat -constraints=
[-outputdir=]
[-collapsesimpleelements=]
[-ignoreidattributes=]
[-javapackage=]
[-root=]

参数解释如下:

参数 必须 默认值 描 述
constraints yes 无 指定产生java代码的约束文件(dtd或xsd.文件)
outputdir no 当前目录 放置生成java文件的根目录
collapsesimpleelements no false 是否支持简单元素的精简,所谓"简单元素"就是在dtd文件中描述的没有属性(attribute)的元素(element)。如果这样的简单元素以"精简"形式被zeus解析,则生成的java类使用其父元素的get[elementname]()的形式来得到xml中该元素的值,这种形式比普通的get[elementname]().getcontent()的形式更简便。而且减少了很多不必要的生成类。
ignoreidattributes no false 此参数设定判断"简单元素"的条件:是否将id属性作为条件。设定此参数为true会导致那些只有一个"id"属性的元素被看作是"简单元素"
javapackage no 无 指定生成的java类的包。例如:指定com.zjh.tools后,所有生成的java类都在com.zjh.tools包内。
root no 由dtd解析器决定 确定用于解析的根元素。解析有多个顶级元素的dtd文件时,指定根元素使之生成正确的java类。

继续上面的例子,将例1的xml文件与java objects绑定,第一步要生成java文件,具体方案就是使用zeus.jar中的org.enhydra.zeus.util.dtdsourcegenerator,例2中的customer.dtd文件作为必须的constrains参数。首先执行下列命令:

将customer文件置于c:zeusdtd文件下,建立c:zeuszjhsample,执行下列命令:
c:zeus>.uildinzeus.bat -constraints=dtdcustomer.dtd -outputdir=zjhsample -javapackage =com.zjh.zeustest.binding -collapsesimpleelements=true

查看c:zeuszjhsamplecomzjhzeustestinding文件夹,发现生成了六个文件:customer.java、customerimpl.java、contact_info.java、contact_infoimpl.java、customerunmarshaller.java、unmarshallable.java。

生成的类名有规可循:customer、contact_info是dtd文件中非简单元素的名称,zeus生成与其同名的接口;customerimpl、contact_infoimpl是实现这两个接口的类。customerunmarshaller与unmarshallable看起来有些奇怪,但也不是凭空而来:unmarshallable接口继承自org.xml.sax.contenthandler,提供解析xml合法性的接口,所有的elementimpl类都要继承该接口;customerunmarshaller提供反解码xml的接口,将xml文件输入,返回customer对象。

数据绑定的所有秘密都隐藏在这几个文件中,可以用任何的文本编辑器对其进行编辑。但是就像程序声明所述:修改这些程序也许会导致数据绑定操作的失败。

最后编译这六个java文件:javac *.java,生成class文件。这样,就得到了用于描述xml文件的java类。

5 marshal与unmarshal--xml与java object的转换
通用的xml文件适合不同技术平台之间的数据传输,java对象可以为java程序提供更加方便的使用接口,通过zeus工具生成的java object就像是一座桥梁,将二者紧密地联系在一起(见图1)。它不仅在内部构建了足够的用来描述xml文件各个元素值的属性,更提供了可以将java对象与xml文件相互转化的接口:unmarshal和marshal。

unmarshal:将xml文件"反解码"为javaobject;

marshal:将javaobject"解码"为xml文件。

图1:java对象与xml文件的转换

5.1 unmarshal xml文件到java对象
一旦用zeus生成的java对象被编译,将xml文件转化为java形式的表述就变成了一件简单且惬意的事。这一过程被描述为"反解码(unmarshal)",其实它是zeus根据dtd文件生成的elementimp对象的unmarshal()方法。如同科幻小说中的物品自动制造机,向unmarshal方法投入以java file、writer、或inputstream形式包装的xml文件,一按unmarshal按钮,xml数据的java表示版就轻而易举的诞生了。示例程序(例3)中的customerunmarshal类完成了unmarshal例1中customerinfo.xml的工作,并把结果输出到屏幕上。

package com.zjh.zeustest;
import java.io.*;
import com.zjh.zeustest.binding.*;

public class customerinfo {
public static void main(string[] args) {
if(args.length!=1){
system.out.println("please in put the location of xml file");
return;
}
try{
customer customer = customerunmarshaller.unmarshal((new file(args[0])),false);
system.out.println("姓名:"+customer.getname());
system.out.println("证件号码:"+customer.getid_no());
system.out.println("性别:"+customer.getsex());
system.out.println("出生地:"+customer.getbirth_place());
system.out.println("国籍:"+customer.getnationality());
system.out.println("学历:"+customer.geteducation());
system.out.println("邮政编码:"+customer.getcontact_info().getzip_code());
system.out.println("电话号码:"+customer.getcontact_info().gettel_no());
}catch(exception e){
e.printstacktrace();
}
}
}

例3 unmarshal xml

编译该程序后用下列命令运行:
java -classpath .;..libxerces.jar com.zjh.zeustest.customer unmarshal ..cust.xml

输入如下:

姓名:李俊
证件号码:210106421016001
性别:男
出生地:大连

国籍:中 国
学历:高 中
邮政编码:116001
电话号码:2645677

5.2 marshal java对象到xml文件
把数据从java object的形式转换为xml文件是unmarshal的逆过程,在语义上用的也是marshal(解码)这一名词。下面提供的例子(例4)提供一个数据绑定使用完整的例子:

将cust.xml读入
unmarshal xml
修改java对象的属性值
marshal java对象

package com.zjh.zeustest;
import java.io.*;
import com.zjh.zeustest.binding.*;

public class customermarshal {

public static void main(string[] args) {
if(args.length!=1){
system.out.println("please in put the location of xml file");
return;
}
try{
customer customer = customerunmarshaller.unmarshal((new file(args[0])),false);
contact_info contactinfo = customer.getcontact_info();
contactinfo.setid("0002");
contactinfo.setzip_code("116001");
contactinfo.settel_no("6656456");
customer.setbirth_date("1979-10-1");
customer.setbirth_place("大连");
customer.setcontact_info(contactinfo);
customer.setcustomer_no("1234566");
customer.seteducation("大学");
customer.setid_no("210204197910012233");
customer.setname("李明");
customer.setnationality("中国");
customer.setsex("男");
customer.marshal((new file("marshalcust.xml")));
}catch(exception e){
e.printstacktrace();
}
}
}

例4 marshal javaobject

执行该程序后生成的新的marshalcust.xml如下所示:

<?xml version="1.0" encoding="utf-8"?>

<!doctype customer system "d:zeusdtdcustomer.dtd">
<customer customer_no="1234566">
<name>李明</name>
<id_no>210204197910012233</id_no>
<sex>男</sex>
<birth_place>大连</birth_place>
<birth_date>1979-10-1</birth_date>
<nationality>中国</nationality>
<education>大学</education>
<contact_info id="0002">
<zip_code>116001</zip_code>
<tel_no>6656456</tel_no>
</contact_info>
</customer>

选择zeus的理由与思考:
java与xml是一对天生的兄弟,在所有计算机软件技术都高举xml大旗的时候,有一万个理由实现java与xml的完美结合。sun、apache也提供了功能强大xml解析包,站在巨人的肩膀上(实际上zeus使用了apache的xerces来解析xml),zeus提出的是数据绑定的概念。

从解析到绑定不需要很复杂的实现手法,但却提供给使用者更加简单和灵活的解决方案。编程技术的发展和开放软件的出现为创意提供了更广阔的空间,选择zeus,使用zeus,思考zeus--没有复杂的技术,只有令人赞叹的创意。这也许就是后软件时代程序生存的真谛,我想。

关于作者
钟家豪,目前在中国广东从事金融领域的软件开发,主要致力于j2ee架构、xml、webservice和数据库方面的研究。可以通过 judson78@yahoo.com.cn 与他联系。
 
 
上一篇: xp精华-如何使 java 项目获得更大成功    下一篇: 安全的代价
  相关文档
java助力火星探测 其认证深受重视 11-17
java程序中用servlet容器实现程序监听 11-16
linux + java = lava(岩浆)? 11-17
jni入门教程之helloworld篇 11-17
jdbc和hibernate来写入blob型数据 11-17
java编程中异常问题处理方式的区别和分析 (1) 12-16
java快速排序函数 11-17
用java实现多线程服务器程序 11-16
专家讲解优化derby数据库程序性能 11-17
利用jakarta commons lang简化java 11-17
setmonth 方法 11-16
java 传递对象给期望原始类型参数的方法 11-17
websphere enterprise scheduler 规划管理(1) 11-17
jdk6.0的新特性:使用compiler api 11-17
【新手必读】java入门及faq 11-17
分析讲解java开发语言中的socket机制 11-16
scna认证全面介绍 11-17
java socket编程(1) 11-16
struts 1.2.2 新功能全新体验 11-17
利用java 创建和读取excel文档 11-17
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息