servlet和xml

来源:互联网 发布:gta5优化方法 编辑:程序博客网 时间:2024/06/02 11:44
我们的第一个 servlet 示例 
一个基本的 servlet 
生成 XML 段 
与数据库对接 
小结 
参考资料 
作者简介 



研究 Java servlet 和 XML 如何共同生成 XML 文档和 DOM 树,以及它们如何与数据库对接。本文包括几项有用的技术:使用 HTTP 参数控制 DOM 树的处理与生成,而无需 XML 源文档。 

对 Java 程序员来说,Servlet 和 XML 是最令人振奋的两项技术。本文是为 2000 年 2 月 17 日旧金山 City Java 用户组准备的演示文稿。在本文中您将看到如何使用 servlet 组成一个简单的 XML 文档,构建一个 DOM 树,并将部分内容显示在用户屏幕上,最后您将看到如何从一个数据库查询生成 XML。 

对于本文讨论的示例来说,我们将扩展 HTTPServlet 类。HTTPServlet 类提供了通常与 CGI 程序相关的功能。它支持 put 和 get,并且使您的代码具有对 HTTP 请求标头的完全访问权,包括 UserAgent 域。我们将创建一些简单的 servlet,并说明它们如何处理以 XML 标签标记的信息。在这一过程中我们还将说明文档对象模型 (DOM) 的一些方法。这些简单的应用程序将使您了解当将 servlet 和 XML 组合在一起时您能够做哪些事情。 

第一个 servlet 示例 
作为开始,我们将编写一个用来生成 XML 文档的 10 行 servlet。在构建理解 XML 的 servlet 时,我们将按以下三个步骤进行: 

将内容类型设为 text/xml。 
创建 XML 文档。 
将 XML 文档写回客户机。 
在我们的大多数 Servlet 中,主要精力放在第二步。我们可能根据数据库查询创建一个 XML 文档,也可能基于从客户传送来的 HTTP 参数生成它,或者也可能使用其他类型的数据检索或生成方法。在本文的示例中,将主要考虑 HTTP 参数和数据库查询。 

一个基本的 servlet 
对于第一个示例,第二步“创建 XML 文档”不是我们所关心的;我们只想生成一个有效的 XML 文档。我们已将文档硬编码到源代码中,如清单 1 所示。 

彩色编码 
彩色编码清单是本文的一个特色,我们正在 dW 进行试验。为了生成我们的彩色编码清单,我正在使用一些开放源代码的工具。首先,我将文档(Java、HTML、XML 等)载入 Emacs 中。Emacs 定义了关键字、注释、函数名以及其他编程语言构件(大约有十多种)的颜色。在 Emacs 载入文件并为其加上颜色以后,我使用 HTMLize 程序包,这是一种用曾经流行的 Emacs Lisp 语言编写的开放源代码实用工具。HTMLize 接收一个清单(这个清单看起来与在 Emacs 中完全一样),然后将其转换为 HTML。结果将是一个完全彩色编码的文件,它突出显示关键字、注释、函数名等。 

请告拆我们您对这些新的、改进的代码清单的想法。 

如果您也想这样做,请参阅参考资料中的相应链接。 


清单 1. xmlfromscratch.java public class xmlfromscratch extends HttpServlet 

  public void service(HttpServletRequest request, 
                      HttpServletResponse response) 
    throws IOException, ServletException 
  { 
    response.setContentType("text/xml"); 
    PrintWriter out = response.getWriter(); 
    
    out.println("<?xml version=/"1.0/"?>"); 
    out.println("<greeting language=/"en_US/">"); 
    out.println("  Hello, World!"); 
    out.println("</greeting>"); 
  } 




这一段令人兴奋的代码生成的结果如下所示: 

清单 2. xmlfromscratch.java 的结果 <?xml version="1.0"?> 
<greeting> 
  Hello, World! 
</greeting> 



您可以查看完整清单的 HTML 视图或直接查看 Java 源文件。 

生成 XML 段 
现在,我们已经创建了一个 servlet,它通过硬编码生成一个没有意义的简单 XML 文档。在下一个 servlet 中,我们从零开始生成一个 DOM 树,然后将 DOM 树的一部分显示在请求者的屏幕上。向请求者发送回的 DOM 树部分取决于 servlet 接收到的 HTTP 参数。本例展示了几项有用的技术:使用 HTTP 参数控制 DOM 树的处理与生成,而无需 XML 源文档。 

清单 3 显示了处理 HTTP 参数的代码段: 

清单 3. xmlfromdom.java   public void service(HttpServletRequest request, 
                      HttpServletResponse response) 
    throws IOException, ServletException 
  { 
    response.setContentType("text/xml"); 
    PrintWriter out = response.getWriter(); 
    
    Enumeration keys; 
    String key; 
    String requestedSubtree = ""; 

    keys = request.getParameterNames(); 
    while (keys.hasMoreElements()) 
    { 
      key = (String) keys.nextElement(); 
      if (key.equalsIgnoreCase("subtree")) 
        requestedSubtree = request.getParameter(key); 
    } 



正如在上一个示例中那样,我们将内容类型设置为 text/xml。在此之后,我们使用 HttpServletRequest.getParameterNames 方法从 HTTP 请求中检索所有参数。 

在处理完这些参数以后,我们需要查找用户所请求的信息。我们使用的信息从对象中构建 DOM 树;该 DOM 树包含了莎士比亚十四行诗的文本,以及关于这首十四行诗的其他信息。我们将根据 HTTP subtree 参数返回 DOM 树的一部分。清单 4 显示了构建 DOM 树的部分代码: 

清单 4. 构建 DOM 树   Document doc = null; 
  Element author = null; 
  Element lines = null; 
  Element title = null; 

  public void initialize() 
  { 
      doc = (Document)Class. 
        forName("org.apache.xerces.dom.DocumentImpl"). 
        newInstance(); 

    if (doc != null) 
      { 
        Element root = doc.createElement("sonnet"); 
        root.setAttribute("type", "Shakespearean"); 
  
        author = doc.createElement("author"); 
  
        Element lastName = doc.createElement("last-name"); 
        lastName.appendChild(doc.createTextNode("Shakespeare")); 
        author.appendChild(lastName); 



我们创建了一个 Java 类的实例,该类实现了 DOM Document 接口,然后我们要求那个节点为我们创建各种节点。您很容易重新编写这个应用程序,使它通过分析 XML 文件生成 DOM 树。为了简化这个示例(并减少我的工作量),我们定义了一些实例变量来保存准备为其提供服务的节点的值。这些值在类声明顶部声明,并在 initialize 方法中初始化。 

最后一步是将被请求的 DOM 树部分发送给用户。为了实现这一任务,我们使用一个递归方法,printDOMTree,它处理节点及其所有子节点。因为这个方法是递归的,所以我们从文档根节点还是从 DOM 树的其他节点开始并不重要。如果所请求的是我们知道的一个节点,则可以将这个节点传递给方法 printDOMTree。否则,我们可以传递 Document 节点。清单 5 显示了这一步骤。 

清单 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("Can't 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 文档,并将它们的内容发送给客户机。最重要的是,这两种技术都是跨平台技术,可为您的应用程序带来更大的灵活性和可移值性。 
 
原创粉丝点击