当前位置: 首页 > 图文教程 > XML家族 > XML > 通过Java编程处理XML 服务SOA

XML
XML简易教程之四
XML与HTML的结合(上)
XML与HTML的结合(下)
XML入门的常见问题(一)
XML入门的常见问题(二)
XMLHTTP资料
什么是XML
什么是 XML Web Service
XML正在接管Web服务 成为SOA的基础
怎么样在网页上读取远程xml的数据
XML教程—编写结构完整的XML文档
读写xml文件的2个小函数
XML文档的基本操作
初学者如何开发出一个高质量的J2EE系统
优化 JavaScript 代码
自动更新程序的设计框架
使Firefox对XML的处理兼容IE的节点处理方法
WML学习之四 锚和任务
WML学习之五 显示表单
WML学习之六 事件

通过Java编程处理XML 服务SOA


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 67 ::
收藏到网摘: n/a

很多大型软件供应商还在开发各自的 SOA 产品。因此,SOA 领域目前综合了各种技术,包括 Java Business Integration (JBI)、Intelligent Event Processing 和 Business Process Execution Language (BPEL) 服务器。因此,在将各种技术融入到一个解决方案之前,想要从 SOA 中受益的用户组织很可能需要进行大量投资。通过对 SOA 布置如此高的复杂性,行业提前为实现供应商定位铺好了道路,即使 SOA 其中的一项承诺是实现基于标准、面向组件、独立于供应商的计算。在开始代价高昂的迁移过程前,用户组织能够获得一些实用的 SOA 使用体验吗?

    为回答这个问题,本文通过简单的 XML 和一些 Java 代码演示了几个重要的 SOA 原理。本文并不打算介绍 SOA 领域中的所有内容;相反,我们只介绍其中的一些关键部分。例如,您可以考虑使用 RSS 发布 XML 服务定义。但是,在本文的例子中,传输机制使用的是 Java 工具。

    Java 技术和 XML

    Java 技术和 XML 几乎成为了同义词。实际上,我通过 IBM 工具对整篇文章应用了 XML 格式。尽管 XML 取得了显而易见的巨大成功,仍需注意 XML 是一种相当笨拙的技术,例如 和 标签会增加大量带宽并在通过网络传输数据时处理系统开销。然而,忽略这种特性,XML 确实提供了一些强大的处理工具。这些工具(本文将探讨其中的两种)基本上解决了数据表示和解析问题(后者长久以来一直难以解决)。现在,通过使用 XML 工具,各种技术级别的程序员都可以实现专业的标准化解析。

    Java 技术为 XML 数据处理提供了一些真正强大的工具(请参见侧栏 Java 技术和 XML)。如果将 清单 1 中的内容看作是给定数据集的基于 XML 的呈现,那么您还可以使用其他方式进行呈现。构成 清单 1 基本内容的原始数据一般保存在数据库中。因此,您如何将这些数据打包成 XML?

    这种聚焦式方法的优点就是用户组织中的 Java 开发人员可以使用其中的理念构建自己的简单的试验性 SOA。这种试验模式有助于组织实现 SOA 的商业效益。后者包含对业务服务建模,例如计算服务、用户自助服务、更好的自动化服务和更具响应性的服务。您可以将上述的迁移作为一个独立试验实现,与现有业务流程并行运作。

    用户组织不需要进行大型投资就可实现一个试验性质的 SOA。通过这种方式,陈述特定于组织的 SOA 需求时可以脱离任何供应商实现。实际上,某些较小的用户组织可以继续使用他们的试验性 SOA 模式,只在后期迁移到软件供应商提供的大型商用解决方案。

    自助服务趋势

    对于大多数服务提供商来说,自助服务正在发展为一种趋势 — 特别是那些资金紧张的 ISP。因此,如果您需要更多带宽(进行下载或玩在线游戏),您可以登录到提供商的 Web 站点并通过 Web 页面自动升级与提供商的连接。让我们看一个具体的例子:清单 1 展示了一个简单的基于 XML 的用户服务配置文件。

    清单 1. 一个简单的基于 XML 的服务描述

    < ServiceInstance>

    < Customer>Josephine Bloggs< /Customer>

    < Package>Internet< /Package>

    < Bandwidth>1mbps< /Bandwidth>

    < DownloadLimit>1Gbyte< /DownloadLimit>

    < Uptime>95< /Uptime>

    < /ServiceInstance>

代码解释了这个用户 XML 服务模型。该模型包括:

    一个服务实例

    客户名字

    服务包的名称

    已配置的带宽量

    每月允许的下载限度

    提供商正常运行时间保证

    无疑,服务定义可以比此处的例子复杂很多。其他内容可能包括客户地址、账单明细、往返延迟、加密和服务信用信息等。重点是,越来越多的提供商提供如 清单 1 所示的 Web 访问细节。某种程度上讲,这种尝试可以减少支持电话的花销和发生频度。有趣的是,这种基于 Web 的服务可以使用户觉得为他们提供服务的是较为先进的提供商。这实现了双赢的局面,因为客户可以更好地访问他们的服务数据,而提供商可以销售无需他们插手的服务包。授权的用户可以修改如 清单 1 所示的一些服务参数 — 例如,配置的带宽。随之修改的是用户每月的订购费用。

    因此,清单 1 中的代码形成了基于 XML 的服务模型的基础。通过简单地与在线表单进行交互,用户可以修改可写的服务元素(例如带宽)。通过在线表单进行的修改将被记录,然后反映到可由用户配置文件修改的后端服务中。这是一种实现自助服务的标准方法。

    然而,您将要了解的是另一种更加松散耦合的自助服务 — 使用这种服务,用户可以通过在网络中传输 清单 1 中的 XML 内容修改数据。在这种场景中,所传输的 XML 内容可通过一个 Java 客户机进行修改,后者可运行在台式机、笔记本电脑、甚至某种资源受限的设备上(例如手机),然后将数据发回给网络服务提供商。这种机制超越了基本的 HTML 页面模型并采纳了 SOA 思想。

    将服务定义 XML 文档传输给使用 Java 技术的客户机

    清单 2 中的内容摘取自本文附带的 Java 文件 encodeXML.java.(相关文件可从 下载 部分获得)。encodeXML.java 类对 XMLEncoder 类的对象进行了实例化。如您所见,这个对象随后在当前目录中创建了名为 xmldata.xml 的文件。下一步是将 XML 数据值插入到文件中,这可以通过调用一连串的 writeObject() 方法实现(清单 2 对此进行了说明)。显然,在生产环境中,清单 2 中硬编码的文本字符串将来自数据库这样的持久性存储。无论何种情况,可以看到 XML 数据文件的创建非常简单。

    清单 2. 使用 XML 格式编码数据

    XMLEncoder e = new XMLEncoder(

    new BufferedOutputStream(

    new FileOutputStream("xmldata.xml")));

    e.writeObject("Josephine Bloggs");

    e.writeObject("Internet");

    e.writeObject("1mbps");

    e.writeObject("Gbyte");

    e.writeObject("295");

    e.close();

执行 清单 2 中的程序后,程序的执行目录中将出现一个名为 xmldata.xml 的文件。清单 3 解释了新创建文件包含的内容。

 

    清单 3. 生成的 XML 数据

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

    < java version="1.5.0_06" class="java.beans.XMLDecoder">

    < string>Josephine Bloggs< /string>

    < string>Internet< /string>

    < string>1mbps< /string>

    < string>Gbyte< /string>

    < string>295< /string>

    < /java>


    您可以通过网络将 清单 3 中的文件传输给等待状态中的客户机 — 使用 Java 技术即可创建。清单 4 展示了一个简单的例子。

    清单 4. 跨越网络传输文件

    byte[] bytes = new byte[BUFFER_SIZE];

    FileInputStream inputFile = null;

    try

    {

    File file = new File("xmldata.xml");

    if (file.exists())

    {

    inputFile = new FileInputStream(file);

    int ch = inputFile.read(bytes, 0, BUFFER_SIZE);

    while (ch != -1)

    {

    output.write(bytes, 0, ch);

    ch = inputFile.read(bytes, 0, BUFFER_SIZE);

    }

    }


    清单 4 中的代码创建了一个长度缓冲区 BUFFER_SIZE。 BUFFER_SIZE 常量的值可以是 1024 或更高。通过调用 inputFile.read() 方法将输入文件(xmldata.xml)的内容读取到缓冲区中。进行缓冲之后,output.write() 方法将文件数据写入到 OutputStream 对象的套接字中。最后一步将数据通过网络发送到等待中的客户机中。这些功能居然只需要这么少的代码!

 

    接下来,您需要使客户机处理传入的 XML 数据。

    接收数据的 Java 客户机获得 XML 内容(并不是 XML 文件)

    客户机如何接收 XML 数据?同样,对于 Java 技术来说这只是小事一桩。数据接收通过一个套接字对象完成。清单 5 展示的代码将接收传入的数据并将数据推入到 ArrayList 类的对象中。

    客户机现在必须解决两个与所接收数据项的数量有关的问题。由于这是一个松散耦合的场景,您必须假定客户机并不清楚服务配置文件(即 清单 1 中的代码)中包含了多少 XML 数据项。因此,您必须确定一些方法来接收和处理精确的数据项数量。第二个问题比较容易解决,就是如何保存处理过的数据。您将看到,清单 5 同时解决了这两个问题。

    清单 5. 提取嵌入的 XML 数据

    XMLDecoder d = new XMLDecoder(input);

    try

    {

    while (true)

    ArrayList< Object[]> rowList = new ArrayList< Object[]>();

    {

    String dataItem = (String)d.readObject();

    System.out.println("XML decoded data: " + dataItem);

    rowList.add(dataItem);

    }

    }

    }

    catch (Exception exc)

    {

    if (exc instanceof ArrayIndexOutOfBoundsException)

    {

    // No more records to process

    System.out.println("Parsed all XML records - " +

    "threw exception. Number of rows: " + rowList.size());

    }

    }

    d.close();

通过一个有限循环 while (true),您可以确定期望的到来数据项的数量。该代码将一直执行循环,直到接收到最后一个数据项,此时将抛出一个异常(ArrayIndexOutOfBoundsException)。您必须使用这种异常机制,除非客户机已经了解期望的数据项数量。

 

    从InputStream 对象接收的 XML 数据被保存在 ArrayList 类的一个对象中。该类对于此类应用程序非常有用。完成类定义之后,ArrayList 具有一个特定的容量,总是匹配底层列表的大小。在添加元素时,ArrayList 对象的容量将自动扩展。因此,您无需担心会超过数组的极限,因为该类将为您处理这一问题。

    此时,客户机具有 清单 1 中数据的副本。客户机现在可以将带宽元素修改为所需的值,然后反向执行文件传输过程,从客户机发送到服务器。通过将 XML 文件从服务器移动到客户机,客户机实际上使用了这一服务。更新后的数据被发送回服务器以完成事务。当然,服务提供商必须验证传入的数据并提供所需的带宽更改。

    本文描述的这种模式首先将一个 XML 文件通过网络传输到客户机。客户机将文件数据作为流进行接收,然后将其解析为一个内存驻留对象。客户机随后对内存驻留对象进行更改,然后反向执行传输过程,将对象发回到服务器。

    还存在一种服务,其中 XML 数据被完整无缺地从服务器传输到客户机。这种场景中,客户机使用某种形式的文件传输协议(例如 FTP)获得完整的文件副本。由于文件传输是一种标准技术,这里不作过多介绍,您只需了解客户机将下载 清单 1 中服务配置数据的一个文件副本。此时,客户机需要解析并修改文件,然后传输回服务器,这种模式的工作原理是什么?

    一种基于 XML 文件的 Java 机制

    客户机现在将服务配置文件的副本保存在磁盘中。必须对该文件进行解析以提取 XML 数据。让人意外的是,这实现起来有些难度,对于较大的文件尤其如此。解决问题的关键是使用合适的解析工具。本文中使用的工具是 dom4j,该工具允许您将 XML 数据解析为一个 Java 对象。您还可以使用一个基于 Simple API for XML (SAX) 的解析器,但是 SAX 是一种较低级的技术。您将看到,dom4j 工具仅需要很少的工作即可完成解析。清单 6 引用自本文附带的ProcessEventXml.java 文件,展示了使用 dom4j 解析文件所需的主要元素。

    清单 6. dom4j 处理 XML 数据

    try

    {

    handler.treeWalk(handler.parse(new File(argv[0])));

    }

    catch (Throwable t)

    {

    t.printStackTrace();

    }

    }

    public Document parse(File url)

throws DocumentException

    {

    SAXReader reader = new SAXReader();

    Document document = reader.read(url);

    return document;

    }

    public void treeWalk(Document document)

    throws Exception

    {

    treeWalk(document.getRootElement());

    }


    基本上只需要两种方法:parse() 和 treeWalk()。当我运行经过编译的类时,我获得了如 清单 7 所示的输出。如果您希望亲自运行代码,请确保下载、安装 dom4j 副本,并添加到 CLASSPATH 中(最后一步就是将相应的 JAR 文件添加到您的 CLASSPATH 变量中)。然后,编译 ProcessEventXml.java 文件并使用以下命令运行程序:

    java ProcessEventXml ServiceDefinition.xml

    清单 7. 使用 dom4j 处理 XML 文件

    java ProcessEventXml ServiceDefinition.xml

    Josephine Bloggs Internet 1mbps 1Gbyte 95

    正如您看到的,仅需少量工作即可整洁地显示 XML 数据。这些工作都是由 dom4j 处理的。事实上,大部分工作是通过 treeWalk() 方法完成的,这是一种只有到达文件末尾才进行调用的递归式方法。这里向您展示了 dom4j 的一个功能:在内存中进行处理。需要注意的是,该技术不适合用于特别大型的 XML 文件,特别是如果您的 Java 设备非常小的话。然而,在本文的例子中,XML 数据集非常小,因此使用这个功能不会产生问题。

    您的基于文件的客户机现在已经成功访问了 XML 数据。客户机可以根据需要修改数据并编写新的 XML 文件。然后将其传输回服务器进行处理。像上文一样,客户机在这一过程中使用了该服务。