`
wangdei
  • 浏览: 366730 次
社区版块
存档分类
最新评论

JAVA分布式应用中使用XML数据

阅读更多

可扩展标记语言(XML)作为一种简单的、中性的、易读的数据表示形式已经变得越来越流行,许多软件厂商宣布的“支持XML",意味着他们的产品将能生成或处理XML数据。XML也被看作再企业间交换数据最佳格式。它允许企业在所交换的数据的XML的文档类型定义(Document Type Definitions,DTDs)或模式(Schema)上取得一致。这些DTDs或Schema是独立于企业使用的数据库模式的。 本文将用研究在不同计算机之间通讯与处理XML数据的分布式系统的构建方法,主要是运行在不同的虚拟机上的JAVA应用之间的XML通讯。 XML通讯 万维网协会(World Wide Web Consortium, W3C)在XML规范中定义了XML的语法和语义。为了处理XML数据,XML文档必须经过解析。W3C定义了文档对象模型(DOM),它是应用程序员处理XML数据的接口。DOM已经有包括JAVA在内的许多语言的实现。JAVA应用程序可以通过DOM API来访问XML数据。XML解析器将产生XML文档的DOM表示。 图1说明了处理XML文档的JAVA分布式应用的简单模型。这个模型假设数据可以从诸如关系数据库之类的数据源得到。JAVA代码处理数据并最终产生DOM表示,这些代码表示为图中的处理器。 处理器代码将DOM代表的XML数据传给发送者。发送者是与接收者进行XML数据通讯的JAVA代码。接收者JAVA代码来接受XML数据,产生DOM表示的数据并把它传送给另一个处理器。简而言之,发送者和接收者抽象了DOM表示的XML数据的通讯。 发送者和接收者不是在同一个JAVA虚拟机上执行的。他们是通过分布式系统的构件来相连的。无论是接收者还是发送者都既是客户端又是服务器端,两者的数据传输都是双向的。 Xbeans 就像将要看到的一样,在本文中描述的发送者和接收者的三种实现方法都都是通过Xbeans来实现。Xbeans是一种接受XML数据作为输入,处理这个输入然后向下一个Xbeans输出XML结果的软件构件。Xbeans的输入输出都是XML的DOM文档,亦即传送给Xbeans的不是需要XML解析器解析的字符串,而是通过W3C的标准DOM API解析成了文档对象。图2说明了一个Xbeans。 Xbeans是JavaBeans,支持封装、重用、连接和客户化Java代码。通过适当的一些Xbeans和JavaBeans的设计工具,我们就能编很少的代码构建非常有用的分布式应用。 Xbeans从IBM的XML的JAVA开发工具包而来,在其上作了少量修改以便更适合分布式的应用。Xbeans能够从www.Xbeans.org的开放源码项目中免费获得。 实现发送方和接收方 下面将介绍用JAVA实现发送者和接收者的三种不同的方法。然后对每种方法作一个简单的分析。 方法一:用标准的web 服务器 这种方法将只是简单的将XML作为文本发送给远程计算机上的web服务器。发送方必须将DOM表示的XML转化为文本来与接收方进行通讯。然后,接受方必须将文本还原为DOM表示,如图3: 以下代码段用HTTP来实现发送者。这里用到了IBM Java开发包中的DOMWriter类来实现DOM表示到文本XML表示的转换。


/**偷窥无罪 http://www.bt285.cn/content.php?id=141970
《我的丑娘》  http://www.bt285.cn/wodechounian/
甜性涩爱 http://www.bt285.cn/1196863/story/story_1.html
public void documentReady(DOMEvent evt) throws XbeansException { try { URL receiver = new URL (getRemoteURL ()); URLConnection receiverConnection = receiver.openConnection(); receiverConnection.setDoOutput(true); //向发送者打开一个输出流然后发送文本形式的XML数据 OutputStream out = receiverConnection.getOutputStream(); DOMWriter writer = new DOMWriter(); writer.setPrintWriter(new PrintWriter(out)); writer.documentReady( new com.ibm.xml.xpk4j.dom.DOMEvent( this,evt.getDocument())); out.close(); // 为结果打开一个输入流 BufferedReader in = New BufferedReader( new InputStreamReader(receiverConnection.getInputStream())); // 处理结果:"OK" 表示成功;"Exception" 表示输入流串行化异常 ... in.close(); } catch (Throwable e) { e.printStackTrace(System.err); } }

注意到以上的documentReady()方法用remoteURL属性得到服务器上的CGI脚本的URL。为了与HTTP兼容,CGI脚本类用字符串”Content-type: text/html"封装接收者的输出。这个脚本然后调用服务器上的the receiverMain()方法。 Main()函数只是简单的实例化接收者然后调用其receiveDocument()方法。



import org.xbeans.communication.stdio.receiver.*; 
public class receiverMain { 
static Bean theReceiver = new Bean(); 
public static void main(String[] args) { 
theReceiver.receiveDocument(); 
} 
} 

最后receiveDocument()方法的代码段将重新生成DOM表示以便进一步处理。这里用到了IBM的XML解析器。



DOMParser parser = new DOMParser(); // 构造解析器 
try { // 调用解析器 
parser.parse(new InputSource(System.in)); 
} catch (Throwable e) { 
throw new XbeansException("","receiver","io error parsing incoming document", 
"io error parsing incoming document "+e); 
} 
//将文档传向下一个bean 
DOMListener.documentReady(new DOMEvent(this,parser.getDocument())); 

方法二:通过JAVA远程方法调用串行化文档 这个方法通过JAVA远程方法调用(JAVA RMI)和DOM串行化(serialization)来从发送者向接收者传输XML DOM 文档。如图4: 以下代码用JAVA远程方法调用实现发送方与接受方的通讯.



public void documentReady(DOMEvent evt) throws XbeansException { 
if (DOMListener==null) { 
try { 
DOMListener = (DOMListener)Naming.lookup(getReceiverName()); 
} catch (Exception e) { 
throw new XbeansException( evt.getDocument().getNodeName(), 
"sender", "error obtaining remote receiver", 
"The name may be wrong or the network may be down."); 
} 
} 
DOMListener.documentReady(evt); } 

以下是接受方的JAVA 远程方法调用的实现。setName()方法将接受这传送给RMI注册(registry),documentReady()方法仅仅将接收到的文档传送给下一个组件。

/**偷窥无罪 http://www.bt285.cn/content.php?id=141970
《我的丑娘》  http://www.bt285.cn/wodechounian/
甜性涩爱 http://www.bt285.cn/1196863/story/story_1.html
public void setReceiverName(String newName) { try { if (receiverName!=null) Naming.unbind(receiverName); receiverName = newName; Naming.rebind(receiverName, this ); } catch( Exception e ) { System.out.println( e ); } } public void documentReady(Document incomingDocument) throws RemoteException, XbeansException { if (DOMListener==null) { throw new XbeansException(incomingDocument.getNodeName(),"rmiReceiver", "next component not established", "The component needs to be configured."); } DOMListener.documentReady(new DOMEvent(this,incomingDocument)); }

方法三:CORBA-IIOP 第三方法用CORBA-IIOP(CORBA over Internet Inter-ORB Protocol)来传输数据。对象管理组织(OMG)正在建议扩展接口定义语言(IDL)将XML数据类型包括进去。这样,将来CORBA产品将能传输XML数据。如图5所示: 以下的OMG IDL给出了发送者和接收者CORBA实现的接口。



exception RemoteReceiverException { 
string remoteIdentifier; 
string documentName; 
string componentName; 
string message; 
string moreMessage; 
}; 
 
typedef sequence byteArray; 
interface XMLReceiver { 
void documentReady(in byteArray serializedDocument) 
raises(RemoteReceiverException); 
}; 

以下代码用JAVA串行化DOM和CORBA实现发送者。



public void documentReady(DOMEvent evt) throws XbeansException { 
Document documentToSend = evt.getDocument(); 
try { 
ByteArrayOutputStream bastream = new ByteArrayOutputStream(); 
ObjectOutputStream p = new ObjectOutputStream(bastream); 
p.writeObject(documentToSend); 
p.flush(); 
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init( new String[0], 
System.getProperties()); 
XMLReceiver receiver = urlToObject(orb,getReceiverURL()); 
receiver.documentReady(bastream.toByteArray()); 
} catch (RemoteReceiverException rre) { 
throw new XbeansException(rre.remoteIdentifier, rre.documentName, 
rre.componentName, rre.message,rre.moreMessage); 
} catch (Throwable e) { 
throw new XbeansException("","sender", "error sending document "+e, 
"error sending document "+e); 
} 
} 

以下代码用JAVA串行化DOM和CORBA实现接收者。



public void documentReady(byte[] serializedDocument)throws RemoteReceiverException { 
// 反串行化字节流 
ByteArrayInputStream bais = new ByteArrayInputStream(serializedDocument); 
Document theDocument; 
try { 
ObjectInputStream ois = new ObjectInputStream(bais); 
theDocument = (Document)ois.readObject(); 
} catch(Throwable e) { 
throw new RemoteReceiverException(corbaName,"incoming document","receiver", 
"error deserializing document","error deserializing document"+e); 
} 
try { //将文档传向监听者 
local.DOMListener.documentReady(new DOMEvent(this,theDocument)); 
} catch (XbeansException xbe) { 
throw new RemoteReceiverException( xbe.remoteIdentifier(), 
xbe.documentName(),xbe.componentName(), 
xbe.message(),xbe.moreMessage()); 
} 
} 

分析: 测试表明,纯文本表示的XML要比DOM串行化表示性能更好。同时,解析DOM和文本所用的时间也要比用JAVA直接串行化和法串行化所用的时间少。 标准的web服务器方式的优势是其应用基础要广泛许多。CGI脚本能够在绝大多数web服务器上运行,而且,接受方能够很容易的通过URL标识。而对于RMI,则需要RMI注册。CORBA的解决办法则需要在服务器上安装对象请求代理(Object Request Broker,ORB ),而且,CORBA发送者的实现使用的是一个URL的命名模式而不是接收者的CORBA对象引用,用一个字符串与一个URL相联系,然后在客户端转化。 CORBA 和RMI支持JAVA 客户端到JAVA服务器的解决方案。没有CGI脚本也不需要从标准输入中读取编码异常。而且,不需要在发送者每次用XML通讯时都启动一个JAVA虚拟机。他们两则均支持接收者的自动激活。 JAVA RMI方式只能在JAVA代码之间工作,对于web服务器包括CORBA理论上能在任何编程语言之间通讯。对于JAVA串行化的DOM来说,即便是客户端和服务器端均需要是JAVA代码的要求不是问题,它还存在另外一个困难,即JAVA串行化要求客户端和服务器运行的是相同的DOM实现。 结论 正如上面所述,有许多方法可以实现在JAVA分布式应用中发送XML数据,每一种方法的性能和互操作性都是不同的。重要的是应该把XML通讯从分布式应用逻辑中抽取出来。也就是,实现发送和接受XML的代码应和应用逻辑的代码中分离出来。通过把代码打包成软件组件,就能够改变发送方和接受方的代码而不会影响到应用其余实现。

分享到:
评论

相关推荐

    用JAVA和XML构建分布式系统

    用JAVA和XML构建分布式系统  本文将用研究在不同计算机之间通讯与处理XML数据的分布式系统的构建方法,主要是运行在不同的虚拟机上的JAVA应用之间的XML通讯。

    基于Java的分布式爬虫搜索引擎机器人设计源码

    本源码提供了一个基于Java的分布式爬虫搜索引擎机器人设计。项目包含1092个文件,其中包括422个JavaScript...这个机器人是一个应用级的分布式爬虫搜索引擎,使用Java语言开发,适合用于大规模数据抓取和搜索引擎构建。

    JAVA_API1.6文档(中文)

    java.sql 提供使用 JavaTM 编程语言访问并处理存储在数据源(通常是一个关系数据库)中的数据的 API。 java.text 提供以与自然语言无关的方式来处理文本、日期、数字和消息的类和接口。 java.text.spi java.text ...

    Java数据编程指南

    使用服务程序进行数据访问 引言 使用服务程序的数据库连接 范例应用程序 JDBC驱动器之结语 小结 第15章 JSP JSP与服务程序 JSP与ASP 实现JSPs JavaServer Page范例 JavaBeans综述...

    xml高级编程(完整版).part1

    第16 章实例研究2 —X M L 和分布式应用程序 第17 章实例研究3 —图书目录信息服务 第18 章实例研究4 —SOAP 附录A XML 1.0 规范 附录B IE 5 XML 文档对象模型 附录C SAX 1.0 :XML 简单API 附录D IE5 ...

    JavaAPI1.6中文chm文档 part1

    java.sql 提供使用 JavaTM 编程语言访问并处理存储在数据源(通常是一个关系数据库)中的数据的 API。 java.text 提供以与自然语言无关的方式来处理文本、日期、数字和消息的类和接口。 java.text.spi java.text ...

    JAVA上百实例源码以及开源项目源代码

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    Java 1.6 API 中文 New

    java.sql 提供使用 JavaTM 编程语言访问并处理存储在数据源(通常是一个关系数据库)中的数据的 API。 java.text 提供以与自然语言无关的方式来处理文本、日期、数字和消息的类和接口。 java.text.spi java.text ...

    基于Java的XML解析与反射设计模式.doc

    关键词:xml java 在web中,多系统间数据交互一般使用webservice技术,它是一种构建应用程序的普遍模 型,可以在任何支持网络通信的操作系统中实施运行;它是一种新的web应用程序分支, 是自包含、自描述、模块化的...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    中文名: 经典Java EE企业应用实战--基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发 原名: 经典Java EE企业应用实战--基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发 作者: 李刚 资源格式: PDF 版本: 第一版 出版社: 电子...

    JAVA上百实例源码以及开源项目

     Java非对称加密源程序代码实例,本例中使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。  设定字符串为“张三,你好,我是李四”  产生张三的密钥对(keyPairZhang)  张三生成公钥(publicKeyZhang...

    java开源包8

    Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端...

    XML高级编程

    在本书样例中使用的查询技术实际起源于XML的样式化,所以本章还承当了显示主线的双重重任。它在这条主线中对于展示查询如何快速找到所需元素,以及如何将不同XML文档关联起来非常有用。第9章(操作XML)也涵盖了出于...

    java开源包4

    Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端...

    java开源包11

    Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端...

    java开源包6

    Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端...

    java开源包101

    Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端...

    java开源包9

    Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用程序)。 重复文件检查工具 FindDup.tar FindDup 是一个简单易用的工具,用来检查计算机上重复的文件。 OpenID的Java客户端...

Global site tag (gtag.js) - Google Analytics