服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

教您如何用zeus实现xml-java的数据绑定

教您如何用zeus实现xml-java的数据绑定
  作者:钟家豪  来源:http://www.cjsdn.net

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文件的版本是1.0,用的是"gbk"的编码方式(如果要解析中文,gbk或gb2312是必须的)。、是的子标记。而在< contact>中还可以继续包含子标记:、。用户自定义tag的xml语言给了用户足够的自由度表示数据,但是也为显示和解析带来了难度,为了解决这一问题,w3c在格式控制和标记定义上对xml加以限制。例如就是一对不合格的标记。
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。可以在zeus/lib下找到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的所有源代码,并将之放置于build/classes下;
bin:将原src/bin下的文件拷到build/bin下,原lib目录下的jar文件拷到build/lib下并将组合好的zeus.jar置于此文件夹下;
doc:编译javadoc,并将结果拷到bin/docs/apidoc/下。
sample和test分别用于编译例程和测试代码。如果不想一步一步编译,可以将targers参数设为all,这样ant就会以正确的次序为你自动编译好所有的targets。编译后的会出现一个build文件夹,所有编译好的文件都在这个文件中。
检查build/bin文件夹,出现的zeus.jar文件就是编译好的工具。如果你有足够的经验去修改zeus的源代码和build.xml文件,完全可以打造属于你自己的zeus。
4、生成描述xml的java对象
生成java对象的第一步是使用zeus自动生成java源代码。使用zeus的批处理文件在build/bin/的zeus.bat,使用语法如下:
 
zeus.bat -constraints=
[-outputdir=]
[-collapsesimpleelements=]
[-ignoreidattributes=]
[-javapackage=]
[-root=]
 
 
将例1的xml文件与java objects绑定,第一步要生成java文件,具体方案就是使用zeus.jar中的org.enhydra.zeus.util.dtdsourcegenerator,例2中的customer.dtd文件作为必须的constrains参数。首先执行下列命令:
将customer文件置于c:/zeus/dtd文件下,建立c:/zeus/zjhsample,执行下列命令:

c:/zeus>./build/bin/zeus.bat
-constraints=dtd/customer.dtd
-outputdir=zjhsample -javapackage
=com.zjh.zeustest.binding
-collapsesimpleelements=true
 
 
查看

c:/zeus/zjhsample/com/zjh/
zeustest/binding文件夹,
发现生成了六个文件:
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文件。
 
 
教您如何用zeus实现xml-java的数据绑定
图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 ./;../lib/xerces.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:/zeus/dtd/customer.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--没有复杂的技术,只有令人赞叹的创意。这也许就是后软件时代程序生存的真谛,我想。

扫描关注微信公众号