服务热线:13616026886

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

位置:首页 > 技术文档 > JAVA > 核心技术 > 查看文档

通过java编程处理xml 为soa减少内存占用

  java 技术为 soa 设计和实现提供了经过优化的解决方案。通过使用简单的基于 xml 文件的服务配置,您可以轻松地在网络中移动客户机数据。客户机可以查看并修改这些数据,然后使用这些数据更新服务。

  很多大型软件供应商还在开发各自的 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 文件。然后将其传输回服务器进行处理。像上文一样,客户机在这一过程中使用了该服务。

扫描关注微信公众号