首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 冲浪宝典-> 邮件工具
XML应用与XGen实战-JSP教程,Java与XML
作者:网友供稿 点击:8
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
如今似乎任何的软件开发都离不开xml技术支持,在图形图像、数据库、加密安全、软件工程、网络教育、电子商务、语音技术上都有xml施展拳脚的地方,xml应用大潮已经来临。 

xml工作小组创始会员c.m. sperberg-mcqueen认为:“xml最大的影响在于xml软件大量兴起:xml剖析器、xml程序语言库、xslt处理器、xsl fo处理器、数据库接受xml—不只如此,还有网络浏览器也接受xml。”也正因为如此,ibm、微软、sun、惠普、oracle等大公司纷纷进入这个市场。

在学会了xgen等对象绑定工具后,相信大家已经是跃跃欲试,希望立刻用xgen来实战一下,体验一下xml对象绑定的优势。下面就介绍一下我经常用到的xml应用。

1. xml配置文件
每个系统可能都需要或大或小的配置文件,通过配置文件来初始化系统的参数,好处不用详细介绍了。一般配置文件的格式有以下种:

1. window系统中ini格式文件和java语言中使用的properties文件

2. xml格式的文件

3. 其他格式文件

第一种类型的配置文件是纯文本文件,基本采用“key = value”的格式来记录各种参数,便于手工书写和阅读。

基于xml schema的xml文件易于阅读,并且能非常好的显示各个元素之间的层次关系和约束关系。相对于ini文件格式使用xml格式的配置文件有以下优点:

1.1. 配置具有层次性

1.2. 取值有效性检查

1.3. 支持链表,枚举,复杂数据类型

1.4. 配置文件可以嵌套

1.5. 结合xml spy 等xml编辑工具编辑配置文件十分便捷

1.6. 存在大量第三方的xml对象绑定工具,并且功能强大、开发便捷。如java语言版的xgen、jaxb,c++版工具 xbind

现在就使开始实践使用xml作为程序使用的配置文件吧。

1.1. 设计xsd文件(xml schema)
xgen需要编译的是xsd文件,xsd文件是用来描述指定类型的xml文件的大纲文件,是个纯文本文件。通过本文编辑工具就可以手工创建、编辑xsd文件,但是通过一些xml编辑工具可以事半功倍的完成xsd编写工作。我也用过一些xml编辑工具,但是只有xml spy的功能最强大,并且使用非常方便。

xml spy 的一些特性:

l 在编辑xml、xsd等文件时具有提示输入功能,可以非常方便的选择。

l 同时具有xml文件合法性校验功能,可以判断element值的取值是否符合schema的定义。

l 支持dtd和xsd互转

l 提供xsd的样例xml实例文件功能

l 同样支持java,c++,c#的xml绑定,可以生成java,c++和c#代码,不要太强大哦!

通过xml spy编写alertserver.xsd 文件

<?xml version="1.0"?>

<xsd:schema targetnamespace="urn:com:lianchuang:smartsecurer:alert:config:configfile.xsd" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns="urn:com:lianchuang:smartsecurer:alert:config:configfile.xsd" elementformdefault="qualified" attributeformdefault="unqualified" >

<xsd:element name="config" type="conifgtype"/>

<xsd:complextype name="conifgtype">

<xsd:sequence>

<xsd:element ref="globe"/>

</xsd:sequence>

</xsd:complextype>

<xsd:element name="globe" type="globetype"/>

<xsd:complextype name="globetype">

<xsd:sequence>

<xsd:element ref="alertserver"/>

<xsd:element ref="vomanager" maxoccurs="unbounded"/>

</xsd:sequence>

</xsd:complextype>

<xsd:element name="alertserver" type="alertservertype"/>

<xsd:complextype name="alertservertype">

<xsd:sequence>

<xsd:element name="id" type="xsd:int"/>

<xsd:element name="address" type="xsd:string" default="127.0.0.1" minoccurs="0"/>

<xsd:element name="port" type="xsd:int" default="1099" minoccurs="0"/>

<xsd:element name="alertservername" type="xsd:string" minoccurs="0"/>

<xsd:element name="registerinterval" type="xsd:int" default="1000" minoccurs="0"/>

<xsd:element name="cachesize" type="xsd:int" default="10000" minoccurs="0"/>

<xsd:element name="deliverthreadnum" type="xsd:int" default="2" minoccurs="0"/>

<xsd:element ref="dbopermode" default="default" minoccurs="0"/>

<xsd:element name="batchdbinsertsize" type="xsd:int" default="1000" minoccurs="0"/>

<xsd:element name="statisticsinterval" type="xsd:int" default="1000" minoccurs="0"/>

</xsd:sequence>

</xsd:complextype>

<xsd:element name="vomanager" type="vomanagertype"/>

<xsd:complextype name="vomanagertype">

<xsd:sequence>

<xsd:element name="address" type="xsd:string"/>

<xsd:element name="port" type="xsd:int" default="1099" minoccurs="0"/>

</xsd:sequence>

</xsd:complextype>

<xsd:element name="dbopermode">

<xsd:simpletype>

<xsd:restriction base="xsd:string">

<xsd:enumeration value="default"/>

<xsd:enumeration value="native"/>

</xsd:restriction>

</xsd:simpletype>

</xsd:element>

</xsd:schema>



注意 <xsd:schema> 设置

elementformdefault="qualified" attributeformdefault="unqualified" 属性

,否则在unmarshal(inputstream ,valid)方法调用中会有异常。这样设置表示限制局部元素和属性,即对每个局部的元素都要设定前缀。

当将 elementformdefault 设置为 qualified 时,它表示在该语法的实例中,必须使用前缀或通过设置 {默认命名空间} 来显式限定所有元素。unqualified 设置意味着只有全局声明的元素才必须被显式限定,而局部声明的元素不得被限定。在此情形下,限定一个局部声明是错误的。同样,将 attributeformdefault 设置为 qualified 时,必须使用前缀显式限定实例文档中的所有属性。

1.2. 创建java对象
进入xgen安装目录,为了省事将alertserver.xsd文件拷贝到该目录下。执行以下脚本:

xgen alertserver.xsd

在当前目录下,会按照urn 路径生成 com\lianchuang\smartsecurer\alert\config\configfile_xsd 目录,并且新创建的class文件就保存在该目录下。若在xsd中定义了自定义复杂类型数据,则会在 configfile_xsd

目录下创建 \type 目录,并把相关的java class 放在该目录下。

1.3. 编写代码
对于定义xsd文档,每个复杂类型的elementa,会有elementa和elementatypecomplextype类来作为该java类的映射,通过getelementatypecomplextype()方法直接可以获取获取elementa的复杂对象类型的引用。

如在xsd文件中的globe,可以通过xxx.getconifgtypecomplextype().getglobe()来获取该java对象,通过config.getconifgtypecomplextype().getglobe().getglobetypecomplextype()来获取实际的该类型的对象。

对于一些基本类型element。xgen定义了一些x开头的类与之对应,如int,用xint表示。可以通过new xint(int i)来构造xint对象。

// 下面是读取指定的配置文件,返回 java 对象的代码

public static synchronized config getconfig(string filename) throws

filenotfoundexception

{

// 创建inputstream对象

file file = new file(filename);

fileinputstream ins = new fileinputstream(file);



chainedentityresolver er = new chainedentityresolver();

unmarshaller un = new unmarshaller(er);

globalelement ge = null;

try

{

ge = un.unmarshal(ins, false); // 注意,由于本人对xml和xsd也是一知半解,unmarshal的方法尝试了一遍,只有使用这个方法,才可以正常转化xml文件的对象。不知道为什么…



if (ge != null && ge instanceof config)

configinstance = (config) ge;

}

catch (validationexception ex)

{

m_log.error(ex);

}

catch (marshalexception ex)

{

m_log.error(ex);

}

catch (ioexception ex)

{

m_log.error(ex);

}

return configinstance;

}

// 下面是打印对象各个属性参数的样例代码

public static void printconfig(config config)

{

if (config == null)

return;

m_log.debug("================ alertserver parameters ==================");

m_log.debug("id = " +

config.getconifgtypecomplextype().getglobe().

getglobetypecomplextype().getalertserver().

getalertservertypecomplextype().getid());

m_log.debug("address = " +

config.getconifgtypecomplextype().getglobe().

getglobetypecomplextype().

getalertserver().getalertservertypecomplextype().getaddress());

m_log.debug("port = " +

config.getconifgtypecomplextype().getglobe().

getglobetypecomplextype().

getalertserver().getalertservertypecomplextype().getport());



m_log.debug("alertservername = " +

config.getconifgtypecomplextype().getglobe().

getglobetypecomplextype().getalertserver().

getalertservertypecomplextype().getalertservername());

m_log.debug("registerinterval = " +

config.getconifgtypecomplextype().getglobe().

getglobetypecomplextype().getalertserver().

getalertservertypecomplextype().getregisterinterval());

m_log.debug("deliverthreadnum = " +

config.getconifgtypecomplextype().getglobe().

getglobetypecomplextype().

getalertserver().getalertservertypecomplextype().

getdeliverthreadnum());

m_log.debug("cachesize = " +

config.getconifgtypecomplextype().getglobe().

getglobetypecomplextype().getalertserver().

getalertservertypecomplextype().getcachesize());

m_log.debug("batchdbinsertsize = " +

config.getconifgtypecomplextype().getglobe().

getglobetypecomplextype().getalertserver().

getalertservertypecomplextype().getbatchdbinsertsize());



m_log.debug("================= vomanager parameters ==================");

for (int i = 0;

i <

config.getconifgtypecomplextype().getglobe().getglobetypecomplextype().

getvomanagercount();

++i)

{

m_log.debug("vomanger address = " +

config.getconifgtypecomplextype().getglobe().

getglobetypecomplextype().getvomanager()[i].

getvomanagertypecomplextype().getaddress());

m_log.debug("vomanger port = " +

config.getconifgtypecomplextype().getglobe().

getglobetypecomplextype().getvomanager()[i].

getvomanagertypecomplextype().getport());

}

}

2. 利用xml格式的消息通信
编写自定义socket通信程序时,都需要自己定义一套通信协议的规范,尤其是异构的系统。我们可以使用xml文档作为通信协议,结合xml相关的对象绑定工具来将xml格式的报文转换为java、c++等语言的对象。

下面以java语言结合xgen使用样例描述通信的流程。

2.1. 通信流程
l 发送xml对象

通过程序创建相关的对象,并赋值。通过unmarshal方法转化为stringwriter对象,使用stringwriter的getbuffer().tostring()方法返回转化好的字符串。最后,利用socket发送该string。

l 接收xml对象

接收到xml文档后,marshal到java对象即可。

2.2. 具体技术
l 通信中加密

由于通过xml文档进行通信,数据包是明文的文本,对于一些敏感数据需要进行适当的加密。如直接对xmlw文档上进行des然后传递,或者根据情况采用更安全的加密方式。

l 发送xml文档

// udp socket

datagramsocket discoverysocket = null;

// 发送的数据包

datagrampacket dgp = null;

// 将xml对象转化stringwriter对象,即转化为字符串对象

stringwriter sw = new stringwriter();

// xml绑定对象

request req = null;

// 需要发送的字符数组

byte[] sendbytes = null;

……

……

try

{

// 创建xml文档对象

req = xmlobjanalysis.makerequset(m_agentdisc.m_configfilename,

getdiscoverrespseqno(),

xmlobjanalysis.discovery_request);



sw.getbuffer().setlength(0);

// 将请求对象序列化为xml字符串

req.getrequesttypecomplextype().setrequestagentip(new xstring(

agentkey.getrequestip()));

req.marshal(sw);

// 将xml文档通过des加密

sendbytes = getdesbytes(sw.getbuffer().tostring().

getbytes(), true);

if (sendbytes != null)

{

dgp = new datagrampacket(sendbytes, sendbytes.length);

dgp.setaddress(ia);

dgp.setport(agentkey.getport());

m_log.debug("send discovery pdu :" + agentkey.getrequestip() +

":" +

agentkey.getport() + ",size =" +

sendbytes.length);

// m_log.debug(new string(sw.getbuffer()));

discoverysocket.send(dgp);

}

}

catch (exception ex4)

{

m_log.error(ex4);

}



l 接收xml文档



ingram =

new datagrampacket

(inbuffer, inbuffer.length);

try

{

for (; ; )

{

try

{



insock.receive(ingram);

}

catch (ioexception ex)

{

m_log.error

("error reading input socket:"

+ ex.getmessage());

// break;

}

catch (exception ex)

{

ex.printstacktrace();

try

{

thread.sleep(100);

}

catch (interruptedexception ex2)

{

}

// return;

continue;

}

recvbytes = new byte[ingram.getlength()];

system.arraycopy(ingram.getdata(), 0, recvbytes, 0, ingram.getlength());

dealagentmessage(recvbytes, hostname);



}

}

finally

{

if (insock != null)

insock.close();

}



private void dealagentmessage(final byte[] origrecvbytes)

{

basicinfo resp = null;

// 解密xml文档

byte[] recvbytes = m_agentdisc.getdesbytes(origrecvbytes, false);

// 将 encoding 标签改为gb2312,这样可以分析出元素中的中文,否则,无法正确转化为中文

string orig = new string(recvbytes);

orig = orig.replaceall("encoding=\"utf-8\"", "encoding=\"gb2312\"");

// 将字符串转化为 bytearrayinputstream

bytearrayinputstream bais = new bytearrayinputstream(orig.trim().

getbytes());

try

{

// 将xml文档转换为对象

resp = xmlobjanalysis.getresponsefromxmlstream(bais);

}

catch (exception ex1)

{

m_log.error(ex1);

}



string requestagentip = resp.getbasicinfotypecomplextype().

getrequestagentip().get();

if (resp == null)

{

m_log.error("decode reponse error.ip = " + requestagentip);

return;

}



// 判断是否是代理自动发现的响应数据

if (resp.getbasicinfotypecomplextype().getresponse().

getresponsechoicecomplextype().getautodiscoveryaschoice() != null)

{

……

}

else if (resp.getbasicinfotypecomplextype().getresponse().

getresponsechoicecomplextype().gethealthcheckaschoice() != null)

{

……

}

}




文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·25m的hotmail免费邮箱申请方法
·用C#下的Raw Socket编程实现网络封包监视-.NET教程,C#语言
·Java JDBC连接的一个例子-JSP教程,Java技巧及代码
·Java Swing入门基础-JSP教程,Java技巧及代码
·Java用户界面本地化实例探索-JSP教程,Java技巧及代码
·有数据绑定、排序、查找功能的ListView(一)-.NET教程,数据库应用
·有线电视3信号放大器特点及常见故障分析
·[ASP.NET]使用C#开发Socket通讯-.NET教程,C#语言
·Session 详解-ASP教程,ASP应用
·ASP.net 2005 Treeview 无限分类非地递归终极解决方案-.NET教程,Asp.Net开发
最新文章
·做google月入一万rmb提示交流_网赚技巧
·英文视频:google adsense技巧视频教程_网赚技巧
·专访51auto创始人:5句话融到4000多万_站长访谈
·站长访谈—sen:骨灰级站长的10年网络生涯_站长访谈
·站长访谈:天涯—曾经的hacker,现在的我_站长访谈
·个人网站如何才能成功?_站长心得
·网站如何获得成功?确定目标是关键_站长心得
·blog广告新创意:review me_站长心得
·利用dns技术解决internet南北互访_站长心得
·googleadsense常用技巧总结_google推广
相关主题
  • XML应用-利用XML 与XSL-.NET教程,XML应用
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭