通过Java编程处理惩罚XML处事界说
副标题#e#
自助处事趋势
对付大大都处事提供商来说,自助处事正在成长为一种趋势 — 出格是那些资金告急的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技能的客户机
Java技能为XML数据处理惩罚提供了一些真正强大的东西(请拜见侧栏 Java技能和 XML)。假如将 清单1 中的内容看作是给定命据集的基于XML的泛起,那么您还可以利用其他方法举办泛起。组成清单1 根基内容的原始数据一般生存在数据库中。因此,您如何将这些数据打包成XML?
清单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>
#p#副标题#e#
您可以通过网络将 清单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);
}
}
#p#分页标题#e#
清单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());}
#p#分页标题#e#
根基上只需要两种要领: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文件。然后将其传输回处事器举办处理惩罚。像上文一样,客户机在这一进程中利用了该处事。