欢迎光临
我们一直在努力

XML应用与XGen实战-JSP教程,Java与XML

建站超值云服务器,限时71元/月

如今似乎任何的软件开发都离不开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)

{

……

}

}

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » XML应用与XGen实战-JSP教程,Java与XML
分享到: 更多 (0)

相关推荐

  • 暂无文章