清单 5. printdomtree
if (requestedsubtree.equalsignorecase("author")) printdomtree(author, out); else if (requestedsubtree.equalsignorecase("lines")) printdomtree(lines, out); else if (requestedsubtree.equalsignorecase("title")) printdomtree(title, out); else printdomtree(doc, out);
|
如果 subtree 参数是 author,则结果是:
<author> <last-name>shakespeare</last-name> <first-name>william</first-name> <nationality>british</nationality> <year-of-birth>1564</year-of-birth> <year-of-death>1616</year-of-death> </author> |
如果 subtree 参数是 title,则结果是:
<title>sonnet 130</title> |
您可以查看完整清单的 html 视图或直接查看 java 源文件。
与数据库对接
我们的最后一个示例是根据数据库查询生成 xml。有许多方法可做到这一点(请参阅 developerworks 的文章 generating xml from a data store);对于本例而言,我们将使用 ibm 的 xml extender for db2(请参阅参考资料)。这个免费产品使您能够在 db2 中存储 xml 文档。我们的查询从 db2 中提取这些文档,然后将其传送给用户。
如果您使用 oracle 8i 代替 db2,您将会发现它自称具有类似的功能(请参阅参考资料)。对于不理解 xml 的数据库,您可以将 xml 文档存储为字符大对象 (clob),并以文本块的方式检索文档。
但是,在安装数据库以后,您需要完成以下三件事情才能使此代码工作:
- 首先,将 dbowner、dbuserid 和 dbpasswd 变量改为适合系统的适当值。
///////////////////////////////////////////////////////////////// // 一定要正确更改这三个字符串,否则 // // servlet 不会工作。 // ///////////////////////////////////////////////////////////////// dbuserid = "xxxxxxxx"; dbpasswd = "xxxxxxxx"; dbowner = "xxxxxxxx";
- 下一步,使用适合您的系统的 jdbc 驱动程序。我们在使用 db2。
static string jdbcdriver = "com.ibm.db2.jdbc.app.db2driver"; ... try { class.forname("com.ibm.db2.jdbc.app.db2driver").newinstance(); } catch (exception e) { system.out.println("cant get the driver!"); e.printstacktrace(); } - 如果你愿意,可以改掉下面的 sql 查询语句。为了简化示例,此处仅检索 sales_order_view 表的 order 列中的全部 xml 文档。
// 我们在此处对 sql 语句进行硬编码;如果根据用户输入 // 限制查询,则情况会更为复杂。 string query = "select order from " + dbowner + ".sales_order_view";
在 service 方法中,我们的 servlet 连接 db2,执行一个查询(其结果为一组 xml 文档),分析查询结果,并将分析过的数据写入输出流中。清单 6 显示了与此关系最密切的代码部分:
清单 6. xmlfromdb2.java
// 我们在此处对 sql 语句进行硬编码;如果根据用户输入 // 限制查询,则情况会更为复杂。 string query = "select order from " + dbowner + ".sales_order_view"; res.setcontenttype("text/xml"); try { coninfo index = new coninfo(); connection con = getcon(index); statement stmt = con.createstatement(); resultset rs = stmt.executequery(query); ... // 显示结果集。我们从每行取出 xml 文档, // 对其进行分析,然后打印 dom 树。当没有更多的行时,rs.next() 返回 // false。 while (rs.next()) { string nextorder = rs.getstring(1).trim(); document doc = null; stringreader sr = new stringreader(nextorder); inputsource isrc = new inputsource(sr); try { parser.parse(isrc); doc = parser.getdocument(); } catch (exception e) { system.err.println("sorry, an error occurred: " + e); } if (doc != null) printdomtree(doc, out); }
|
要了解全部细节,您可以查看完整清单的 html 视图或直接查看java 源文件。
小结
尽管这些 servlet 示例中没有一个可以改变世界,但它们确实展示了 xml 和 servlet 配合得有多么好。servlet 是向客户发送内容的一种伟大机制,而 xml 是发送结构化数据的一种完美机制。您还可以使用 servlet 处理服务器上的 xml 文档,并将它们的内容发送给客户机。最重要的是,这两种技术都是跨平台技术,可为您的应用程序带来更大的灵活性和可移值性。
参考资料
- 了解有关 db2 xml extender 的详细信息。产品附带的文档中有一个深入的教程,它可帮助您将 xml 文档带入关系数据库的世界中。
- 了解有关 oracle 数据库产品的详细信息。
- 试用 websphere 附带的免费 servlet 教程。
- 通过 developerworks 的 xml programming in java 教程深入研究如何分析 xml 文件。
- 下载作者为 city java 用户组制作的演示文稿的 pdf 版本。
- 在 www.gnu.org 网站学习使用 emacs 彩色编码代码清单。htmlize 程序包可从网址 jagor.srce.hr 获得。
