WEB开发网
开发学院数据库DB2 编写操作 DB2 数据的 Web 应用程序(第 2 部分) 阅读

编写操作 DB2 数据的 Web 应用程序(第 2 部分)

 2009-11-06 00:00:00 来源:WEB开发网   
核心提示:Web 应用程序中的主页和 servlet现在准备好将第二个 Web 页面、一个 servlet 及其关联的 ConnectionPool 类与现有的单个页面 Web 应用程序集成,下面是配置 Web 服务器的步骤,编写操作 DB2 数据的 Web 应用程序(第 2 部分), 我们将把新的 JSP 页面添加到应用程序,

Web 应用程序中的主页和 servlet

现在准备好将第二个 Web 页面、一个 servlet 及其关联的 ConnectionPool 类与现有的单个页面 Web 应用程序集成。下面是配置 Web 服务器的步骤。

我们将把新的 JSP 页面添加到应用程序。需要再次启动应用程序组装工具(Application Assembly Tool(AAT)),然后装入 Test_war.ear 文件,该文件是先前为 TestTeam.html 页面而创建的。

展开 Test_war、Web Modules、DB2TestSample 和 Files,然后选择 Resource Files。单击鼠标右键,然后选择 Add Files 选项。只需要象先前添加 TestTeam.html 一样将 TestMain.jsp 添加在 Webdirectory 中。这个 JSP 文件还使用 bgsnd.mid 和 blob.gif 资源文件。同样,象先前所做的那样,需要从 resource 目录中选择这些文件。

保存文件。

请注意 图 5中的倒数第二行:JSP:include。 因为我们还没有准备好 JSP,所以您需要编辑那个文件并删除那一行。稍后我们将把它添加回去。这一步“非常”重要,不要跳过,否则 TestMain.jsp 页面将无法在浏览器中工作。

回到 Administration Console。展开 Enterprise Application,然后选择 TestSample。单击鼠标右键,然后单击 Stop。在它停止后,再次重复这些步骤,只不过这次选择 Remove。

在 Console 菜单项中依次选择 Wizards 和 Install Enterprise Application。象以前所做的一样,装入 Test_war.ear 文件。

转至 Nodes,选择您的节点,然后单击鼠标右键。选择 Regen Webserver plugin。

现在选择 Application Servers,然后选择 Default Server。在 Stop 上单击鼠标右键,然后单击 Start 再次开始。
打开所选的 Web 浏览器。输入 URL:http://your-machine-name/testTeam/Web/TestTeam.html。迅速出现 TestTeam.html 页面。这次的区别是:8 秒后显示的不是错误页面而是 TestMain.jsp 页面。Anakin Skywalker 现在一定很兴奋。

注:在实际的 Web 环境下,您不会将源代码放在 servlets 目录中,而只会放入 .class 文件或者包含这些类文件的 .jar 文件。为了简单起见,我已将源代码都放在了一起。理想情况下,将在单独的目录中编译源文件,并且将仅复制运行 Web 所需的可执行代码。

同样,在上面添加 .class 文件的步骤中,您必须确保在 Root Directory 域中输入正确路径。如果不这样做,您将以“servlets”结尾作为路径的一部分,而这并不是我们希望的。

先前我们从 TestMain.jsp 中除去了 JSP:include 这一行以装入并运行 JSP 屏幕。现在,我们将把它添加回去。这将是 servlet 代码的第一段。我们将添加新的 Web 组件, 添加类文件,然后创建 servlet 映射。

在 servlets 目录中有文件 DBBean.java 和 ConnectionPool.java。我们所做的 前期步骤之一是安装 Java 开发者工具箱(JDK)。为了编译 servlet Java 代码,现在需要修改 CLASSPATH 环境变量。我们需要向其添加 <install-path>/appserver/lib/j2ee.jar;。这最好是通过选择桌面上的 My Computer->Properties 然后选择 Advanced 选项卡,接下来选择 Environment Variables 按钮来完成。在 System Variables 部分选择 CLASSPATH,然后选择 Edit 按钮。在 variable value 域,添加 <install-path>/appserver/lib/j2ee.jar;。按三次 OK 按钮。

需要对已编写、复制和修改的 Java 代码进行编译。打开一个 MS-DOS 命令提示窗口,然后切换至有样本代码的目录。输入命令 javac DBBean.java。这将在当前目录生成 DBBean.class 和 ConnectionPool.class 文件。

通过选择 Start->Programs->WebSphere->Application Assembly Tool 从桌面 Start 菜单启动 AAT。装入 Test_war.ear 文件。

展开 Web Modules、DB2TestSample 和 Files。在类上单击鼠标右键,然后选择 Add Files。现在,我们将添加这两个类文件。在 Root Directory 中输入到这两个类文件的路径:<samples-path>/servlets。按 Enter 键。

选择 ConnectionPool.class 然后按 Add 按钮。对 DBBean.class 文件采用相同操作,然后按 OK 按钮。

回到 AAT,现在您将看到添加的两个类文件。接下来,我们要添加 DBBean servlet 作为 Web 组件。选择 DB2TestSample 项下的 Web Components。在其上单击鼠标右键,然后选择 New。

在 Component Name 中输入 DBBean。可选地输入显示名称和描述。

在 Component Type 下选择 Servlet 单选按钮。在 classname 域中输入 DBBean,或者按 Browse 按钮,然后选择 DBBean。按 OK 按钮。

现在我们要添加一个 servlet 映射。在 AAT 左窗格中选择 Servlet Mapping。单击鼠标右键,然后选择 New。在显示的对话框中,URL Pattern 域中输入 /DBBean。在 Servlet 域中输入 ../DBBean。按 OK 按钮。URL 名称是浏览器所期望的。在我们的例子中,这是我们在 TestMain.jsp 文件内指定的。WebSphere 通过刚创建的 servlet 映射将 URL 映射成实际的 servlet 名称。请注意,我们在 servlet 名称前添加“../”,因为 servlet“别名”到 JSP 的相对路径是“../”;即,JSP 在 testTeam/Web 目录中,而 servlet 别名是 testTeam。

在 File 菜单项下选择 Save 按钮。

现在,我们需要将新更改的应用程序安装到 WebSphere 和 Web 服务器中。启动 WebSphere Administration Console。

要安装保存在 AAT 工具中的新版本,我们先除去现有版本,然后添加新版本。展开 Enterprise Application,然后选择 Test_war 项。单击鼠标右键,然后选择 Remove。

选择 Console 菜单项,然后依次选择 Wizards 和 Install Enterprise Application。选择 Install application (*.ear) 单选按钮。输入到 Test_war.ear 文件的路径,或者使用 browse 按钮来查找它。

单击 Next 按钮直到 Finish 按钮处于激活状态。然后按 Finish 按钮。

您将看到 WebSphere Application 控制台的左窗格用新的应用程序更新过了。

现在展开 Nodes 项,然后展开您的机器名称项。在机器名称上单击鼠标右键,然后选择 Regen WebSphere plugin。

转至 Start->Settings->Control Panel。选择 Administrative Tools。

双击 Services。向下滚动到 IBM HTTP Server,单击鼠标右键,然后选择 Stop,或者从菜单栏选择 STOP 图标。

它停止后,再次启动它,强制它启用我们所做的更改。

返回 Administration Console,从左窗格的 Enterprise Applications 节点下选择 Test_war。单击鼠标左键,然后选择 START。

至此,完成了安装步骤。现在,让我们进行测试来看看它是否工作。从 MS-DOS 命令提示窗口输入命令 DB2JSTRT 3456。这将启动端口 3456 上的 DB2 JDBC 侦听器,该端口就是我们所说的这个应用程序将用来与服务器通信的端口。这需要在正在运行 Web 服务器的机器上完成,该机器可以是正在运行浏览器和/或 DB2 服务器的机器,也可以不是这样的机器。

启动 Web 浏览器,然后输入我们主页的 URL:http://your-machine-name/testTeam/Web/TestTeam.html。就象在初始测试中那样,我们会看到主页大约出现 8 秒钟,然后将自动出现 TestMain.jsp 页面。这里的实际问题是“servlet 正确运行了吗?”。故障的第一个迹象是显示在 Web 浏览器中的错误消息。如果那里没有显示任何信息,则查看 <WebSphere-install-path>/logs 目录中的 Default_server_stdout.log 和 Default_Server_stderr.log 文件。滚动到底部。您会看见 DBBean: init 项,然后是成功或错误消息。如果 DB 连接成功,应该会在 Default_Server_stdout.log 文件中看到 DBBean : made connection pool。

注:日志中的常见错误是连接到 DB2 时用户标识或密码不正确。这是因为您没有编辑 DBBean.java 并将用户标识、密码以及数据库 URL 更改成您的安装值。

它的外观如何?

图 7中的 Internet Explorer 抓屏显示了正在运行的应用程序,并显示主页或至少它的大部分。注意链接的颜色,它基于对 BODY 标记的定义,与 一些真正的 HTML:TestMain.jsp 主页所描述的一样。还请注意,由于表对齐域,所以表单中的所有按钮都和按钮功能的文本描述一样排列整齐。如果您的机器有发声功能,则会听到音乐在播放。最重要的是,滚动到浏览器屏幕的底部,并确保没有显示任何错误。DBBean servlet 应该已经运行并连接到数据库。

如果您熟悉数据库,则可以发出 DBSTOP 命令,然后启动 Web 浏览器和应用程序。在本例中,因为数据库没有在运行,所以数据库连接会失败。您会看见一些故障指示。使用 DB2START 命令重新启动数据库。还可以查看 <install-path>/appserver/logs 目录下的 XXXXstderr.log 文件。使用 Notepad 或类似编辑器浏览该文件。转至底部。您应该“不”会看到任何 SQL 错误。如果看到了,则 DBBean servlet 失败。


图 7:应用程序的主 Web 页面
编写操作 DB2 数据的 Web 应用程序(第 2 部分)

下一步是什么?

如果回过头看一下 图 3,您会看到我已经讨论了前两个页面:TestTeam.html 和 TestMain.jsp 以及由 TestMain.jsp 调用的 DBBean servlet。为了节省空间,我将不详细论述 TestMSP.html、TeamStruct.jsp、TeamStructCl servlet 和 RawData.jsp 文件。我将简要描述 RawData servlet 的一点信息,如 图 6所示。

几乎应用程序中那些片段的每个功能都在下面的类似情况中进行了描述。文件 TestMSP.html 只是显示了当前测试计划的 HTML 表示,这样测试组外的人员可以知道我们在做什么。文件 TeamStruct.html 显示了团队的组织,例如谁进行什么工作。它还显示用于各种软硬件环境的各种测试机器,包括每台机器上测试的产品和发行版。文件 TeamStruct.html 包含 TeamStruct.jsp。这个 JSP 调用 TeamStructCl servlet。JSP 显示表的第一部分,它显示了每个产品的测试用例总数、Java、C/C++、64 位、自动的、手工的、UI 的数目以及其它总数。填充这个表的实际数字是从 TSTCASES 数据库表通过 TeamStructCl servlet 抽取的,并且使用 HTML 表标记进行格式化。

象先前所做的那样,再次启动 AAT 以添加上面的 JSP 和 HTML 文件。这次,我们还将从 resources 目录添加所有其它 *.jpg 文件,因此我将不通过名称列出它们。现在,一起添加它们比每次进行更改更容易。因为我们要添加 TeamStructCl servlet 和 DBaccess servlet(由 TeamStructCl servlet 使用),所以我们还需要遵循 上面的步骤以在 AAT 中注册 servlet。不要忘记为 TeamStructCl 添加 servlet 映射。我们不需要为 ConnectionPool 或 DBaccess Java 文件添加映射,因为它们不是真正的 servlet,只是由 servlet 调用以执行实用程序任务的 Java 代码。它们不象这个示例中的 servlet 那样生成任何 HTML。

保存文件,然后遵循上面的步骤从 WebSphere Administration Console 中删除应用程序,接着再次添加应用程序。这将应用更改。不要忘记像 上面完成的那样重新生成并停止/重新启动 HTTP 服务器。

RawData JSP 和相应的 servlet 用来满足那些想看到每段最新可用信息的人们的需要。从数据库中抽取数据,然后按列显示数据,而不进行任何格式化或合并。完成该任务的代码是从 CoreServlets 一书以及参考资料中提到的网站中复制并稍作修改。我在 DB2 UDB Application Development Certification Guide 中也发现了相似的代码。 图 8 的第一列显示了一种接收行数据和列数据并将数据格式化成 html 表的 Java 方法。注意第 8-10 行,for(int col=0; col<columnCount; col++) buffer.append("<TH>" + columnNames[col]);它在表的顶部显示了列名。第 11-17 行显示了被放入表中各列的实际数据。在第 11-17 行中,您还将看到一个以行为索引的外部循环以及一个以列为索引的内部循环。

第二列,方法 getQueryResults() 从 DB2 获取实际数据。列名被放入字符串数组 ColumnNames 中,如第 8-12 行所示。第 8-12 行设置了正确的环境,以便第 20-31 行可以获取列名。第 5-7 行中的语句显示了从 DB2 抽取的数据,而第 20-31 行接收这些数据并将其存储在一个字符串数组的向量(即二维数组)中。

包含这个示例代码的原因是为了显示使用这么少的代码可以完成多少工作。用这两个简单的方法抽取行数据并进行格式化。

图 8 — RawData servlet

1  public String toHTMLTable(String headingColor) { 
2  StringBuffer buffer = new StringBuffer 
3  ("<TABLE BORDER=1>\n"); 
4  if (headingColor != null) { 
5     buffer.append(" <TR BGCOLOR=\"" + 
6  headingColor + "\">\n "); 
7   } else buffer.append(" <TR>\n"); 
8   for(int col=0; col<columnCount; col++) 
9     buffer.append("<TH>" + columnNames 
10 [col]); 
11  for(int row=0; row<getRowCount(); row++) { 
12     buffer.append("\n <TR>\n "); 
13     String[] rowData = getRow(row); 
14     for(int col=0; col<columnCount; col++) 
15       buffer.append("<TD>" + rowData 
16 [col]); 
17  } 
18  buffer.append("\n</TABLE>"); 
19  return(buffer.toString()); 
20  } 

1  public void getQueryResults() { 
2   Connection c = access.getConn(); 
3   try { 
4    DatabaseMetaData dbMetaData = c.getMetaData(); 
5    Statement stm = c.createStatement(); 
6    ResultSet rs = stmt.executeQuery("SELECT * 
7   FROM TSTRSLTS"); 
8     ResultSetMetaData resultsMetaData = 
9   rs.getMetaData(); 
10     columnCount = resultsMetaData.getColumnCount(); 
11 
12     columnNames = new String[columnCount]; 
13 
14 
15     for (int i=1; i<columnCount+1; i++) 
16      columnNames[i-1] = 
17        resultsMetaData.getColumnName(i).trim 
18 (); 
19 
20    rowData = new String[columnCount]; 
21    queryResults = new Vector(); 
22 
23    while(rs.next()) { 
24     String[] row = new String[columnCount]; 
25     for(int i=1; i<columnCount+1; i++) { 
26      String entry = rs.getString(i); 
27      if (entry != null) entry = entry.trim(); 
28      row[i-1] = entry; 
29    } 
30    addRow(row); 
31    } 
32    return; 
33   } catch(SQLException sqle) { System.out.println 
34 ("Error : " + sqle); 
35   return; } 
36  } 
37 } 

现在,我们正如对上面的 TeamStruct 例子所做的那样添加 RawData.jsp 和 RawDataCl servlet。

象编译其它 Java 文件那样编译 RawDataCl.java。

象上面完成的那样启动 AAT,然后重复上面的步骤。

将 .jsp 添加到 resources 目录的文件列表中。

将 .class 添加到 classes 目录的文件列表中。

将 .class 作为 Web Component 添加。

将 .jsp 作为 Web Component 添加。

为 .class 文件添加 servlet 映射。

按 AAT 中的 save 按钮。

转至 WebSphere Admin Console,删除现有的 Test 应用程序,然后使用向导装入新的应用程序。

不要忘记重新生成插件,接着停止 IBM HTTP 服务器,然后重新启动它。

我不打算一步一步地分别完成这些步骤,因为它们与先前的步骤一样,只是 Java 源文件名已改变(以保持简单!)。请注意,我们没有编译 DBaccess.java。文件 TeamStructCl.java 和 RawDataCl.java 引用文件 DBaccess.java。这样,编译这两个 .java 文件的任何一个时,也会编译引用的文件 DBaccess.java。如果愿意使用同一 javac 命令,则可以编译它。

TeamStruct servlet 从 DB2 UDB 中的 TSTCASES 表装入数据。在运行应用程序,然后单击 Team Structure 按钮之前,我们应该 把数据填充到表中。这是在本文开始期间就完成的,因此只要验证是否完成了那些步骤。

这把我们带到 Test Results 按钮,它是这个应用程序起实际作用的部分。页面上的许多链接都是到简单的 HTML 页面、JSP 和 servlet。这个按钮把我们带到产生显示测试数据的各种格式的 JSP。 图 3很好地显示了这一点,因为 TestResults.jsp 在其下面包含许多 JSP 和 servlet。下面的 图 9显示了 TestResults.jsp。

图 9:TestResults.jsp

1  <HTML><HEAD><TITLE>Test Results</TITLE></HEAD> 
2  <body text="#FF0000" bgcolor="#FFFFFF" link="#FF00FF" vlink="#F00000" alink="#FF8080" 
3  background="../resources/whtmarb.jpg"> 
4  <center><table><td><IMG SRC="http://tech.ddvip.com/resources/WasBanner.gif"></td> 
5  <td><font color="#FF0000"><H1>Test Results</H1></font></td></table> 
6 
7  <table><tr><td><IMG SRC="http://tech.ddvip.com/resources/radioPressed.gif" HEIGHT=34 WIDTH=34></td> 
8  <td><font color="#3333FF"><font size=+1><a href="#Product">Summary by 
9  Product</a></font></font></td></tr> 
10 <tr><td><img SRC="http://tech.ddvip.com/resources/radioSelected.gif" height=34 width=34></td> 
11 <td><font color="#3333FF"><font size=+1><a href="#Platform">Summary by 
12 Platform</a></font></font></td></tr> 
13 <tr><td><img SRC="http://tech.ddvip.com/resources/radio.gif" height=34 width=34></td> 
14 <td><font color="#3333FF"><font size=+1><a href="#Custom">Custom 15Query</a></font></font> 
15 </td></tr> 
16 
17 </table><hr SIZE=4 WIDTH="100%"> 
18 
19 <table><tr><td BGCOLOR="#99FF99"><b> <JSP:include page="../TestTeamCl" 
20 flush="true" /></table></form><hr> 
21 
22 <h2> <a NAME="Custom"><font color="#FF0000">Custom Query</font></h2> 
23 <font color="#3366FF">Enter a product and platform to see history for this combination.</font> 
24 <FORM METHOD="post" ACTION="Custom.jsp"> 
25 <p>Product : <INPUT TYPE="text" NAME="product" VALUE="Distributed Debugger" SIZE="30" 
26 MAXLENGTH="40"> 
27 Platform : <INPUT TYPE="text" NAME="platform" VALUE="NT" SIZE="15" MAXLENGTH="15"></p> 
28 <INPUT TYPE="submit" NAME="SUBMIT" ID="SUBMIT" VALUE="SUBMIT"></form> 
29 <hr></center></BODY></HTML> 

这个 JSP 被分成由空白行分隔的几节。正如使用上面描述的 TestMain.jsp 一样,有一个包含标题、一些图片以及用于各种域和热链接的颜色设置的标题信息。紧接着标题的一节是一张由三行组成的表。每行都非常相似,执行同一功能。那个功能是到页面后面某一节的快速链接。因此,这里有通过 JSP 显示的三节的三个链接。第二个链接,第 10-12 行,是 <tr><td><img SRC="http://tech.ddvip.com/resources/radioSelected.gif" height=34 width=34></td><td><font color="#3333FF"><font size=+1><a href="#Platform">Summary by Platform</a></font></font></td></tr>。这是由封闭的 <tr>...</tr>定义的单个行。在这行内有两个由封闭的 <td>...</td>定义的列。第一列显示类似于 编写操作 DB2 数据的 Web 应用程序(第 2 部分) 的图标,它只是标识行的一种花哨的方法。

第二列包含文本,该文本作为到后续页面中某一节的链接(超文本链接)。通过单击链接,页面会滚动到那一节。在这个例子中,它将滚动到第 11 行中标记为 #Platform 的那一节。# 意味着链接位于同一页面;没有在另一个 URL 上找到链接。因为在这个表中有三行,所以在这个 Web 页面中有三节。看一下 图 9,您可能想知道这三个页面的位置在哪里以及为什么 #Platform 是同一页面中的链接而任何地方都没有 Platform 的标号。答案在第 19-20 行:<JSP:include page="../TestTeamCl" flush="true" />。它包括位于这一位置的 TestTeamCl servlet 输出。

看一下第 19-20 行周围的标记,我们看见一些标记没有匹配的结束标记。例如,有开始一行一列的 <tr><td>,但却没有匹配的结束一行一列的 </td></tr>。类似地,有表示粗体文本开始的 <b>。但是,没有表示粗体文本结束的 </b>。这一问题的答案是匹配的结束标记在 servlet 中产生。请注意,第 19-20 行中 JSP 周围的开始和结束标记注明哪些文本创建并终止表。除了我刚提到的初始的几项以外,servlet 填充表的大部分信息。这个 JSP 中的标记与那些由 servlet 生成的标记的组合就是 Web 浏览器和最终用户所看到的。当您运行应用程序时产生这个页面,然后使用浏览器的 View Source 功能。您将会看见包含来自 JSP 和 servlet 的所有标记的整个页面。

在第 22 行中,标记 <a NAME="Custom"> 是标号的一个示例。我提到了三个标号,这是三个中的最后一个。在第一个表中,可以看到 #Custom,它是到页面中这一节的链接。

最后,我想讨论一下第 24-28 行:<FORM METHOD="post" ACTION="Custom.jsp"> <p>Product : <INPUT TYPE="text" NAME="product" VALUE="Distributed Debugger" SIZE="30" MAXLENGTH="40"> Platform : <INPUT TYPE="text" NAME="platform" VALUE="NT" SIZE="15" MAXLENGTH="15"></p><INPUT TYPE="submit" NAME="SUBMIT" ID="SUBMIT" VALUE="SUBMIT"></form>。这是一个 FORM 标记,用于允许选择一个按钮,将信息传递到那个特定按钮所链接的目标页面。在这个例子中有两个文本域和一个按钮。按下按钮时,将文本域的内容传递到目标页面,在本例中是由 ACTION= field 指定的 Custom.jsp。许多 HTML 书籍以及在参考资料一节中提到的网站上都详尽地描述了表单。简而言知,INPUT TYPE= 域定义了域是什么类型,在这个示例中是 TEXT 或 SUBMIT。text 类型意味着可以通过浏览器在那里输入文本。submit 类型意味着现在将调用由 action 标识的页面。VALUE 域是传递到下一页面的信息。可以象我在这里所做的那样指定初始的缺省值。因此,对于 product,缺省值为 Distributed Debugger。类似地,对于 platform,缺省值为 NT。

图 10:TestTeamCl servlet 代码片断

1  /* 
2  Written by Ed Van Gennip. IBM Canada Limited. 2000 
3  Purpose : Extract from DB2 product and platform test results and 
4      display the results is two tables. Format these tables (html 
5      tags) and pass back to TesTReslts.jsp. 
6  */ 
7 
8  import java.io.*; 
9  import javax.servlet.*; 
10 import javax.servlet.http.*; 
12 import java.sql.SQLException; 
13 
14 public class TestTeamCl extends HttpServlet{ 
15  private DBaccess access; 
16 
17  public TestTeamCl() { } 
18 
19 
20  public void init() { access = new DBaccess(getServletContext()); } 
21 
22  public void doGet(HttpServletRequest httpServletRequest, 
23           HttpServletResponse httpServletResponse) 
24  throws ServletException, IOException { 
25  httpServletResponse.setContentType("text/html"); 
26  printWriter pW = httpServletResponse.getWriter(); 
27  try { access.startAction(); } 
28   catch (SQLException e1) { 
29    System.out.println(new StringBuffer("SQL Exception : "). 
30              append(e1).toString()); 
31  } 
32  String astring[] = access.getLastDateAndDriver(); 
33 pW.println("<font size=+1>Last Update</font></b></td>"); 
34  pW.println("<td>"); 
35  if (astring == null) pW.println("No drivers found"); 
36  else  pW.println(astring[0].substring(0, 19)); 
37  pW.println("</td><td BGCOLOR=\"#99FF99\"><b>"); 
38  pW.println("<font size=+1>Latest Debug/OLT 
39        Driver</font></b></td>"); 
40  pW.println("<td>"); 
41  if (astring == null) pW.println("No drivers found"); 
42  else  pW.println(astring[1]); 
43  pW.println("</td></tr></table>"); 
44  pW.println("<h2><a NAME=\"Platform\"><font color=\"#FF0000\"> 
45        Summary by Platform</font></h2>"); 
46  pW.println("<font color=\"#3366FF\">Summary by platform across 
47      all products for the driver shown above which ship on that 
48      platform. The button in the PLATFORM field takes you to 
49      the details for that platform and its history.</font>"); 
50  pW.println("<FORM METHOD=\"post\" 
51 
52        ACTION=\"Web/Platform.jsp\">"); 
53  pW.println("<table BORDER=3 BGCOLOR=\"#CCCCCC\">"); 
54  pW.println("<tr BGCOLOR=\"#99FF99\">"); 
55  pW.println("<td><b>PLATFORM</b></td>"); 
56  pW.println("<td><b>Total TC</b></td>"); 
57  pW.println("<td><b>Passed #/%</b></td>"); 
58  pW.println("<td><b>Failed #/%</b></td>"); 
59  pW.println("<td><b>Not run # %</b></td></tr>"); 
60  if (astring != null) { 
61 putPlatRow(access, pW, "Windows", astring[1]); 
62   putPlatRow(access, pW, "AIX4.3.3", astring[1]); 
63   putPlatRow(access, pW, "AIX5.0L", astring[1]); 
64   ........... 
65   putPlatRow(access, pW, "S/390", astring[1]); 
66 } 
67 pW.println("</table></form><hr>"); 
68  ... 
69  try { access.endAction(); } 
70  catch (SQLException e2) { 
71   System.out.println(new StringBuffer("SQL Exception :") 
72       .append(e2).toString()); 
73 
74   } 
75  } 
76 
77 private void putPlatRow(DBaccess dBaccess, 
78     printWriter pW, String string1, String string2) { 
79  pW.println("<tr><td><INPUT TYPE=\"submit\" 
80     NAME=\"PLATFORM\" VALUE=\""+string1 + "\"></td>"); 
81  int an[] = dBaccess.queryTotalsByPlatformDriver(string1, 
82           string2); 
83  if (an == null) { pW.println("</tr>");  return; } 
84  pW.println("<td><center>"+an[0] + "</center></td>"); 
85  int i = an[1] + an[2]; 
86  if (i > 0) { 
87     pW.println("<td><center>"+an[1] + "/" + an[1] * 100 / i + 
88           "</center></td>"); 
89     pW.println("<td><center>"+an[2] + "/" + an[2] * 100 / i + 
90           "</center></td>"); 
91  } else { 
92    pW.println("<td><center>"+an[1] + "/0</center></td>"); 
93    pW.println("<td><center>"+an[2] + "/0</center></td>"); 
94 } 
95 if (an[0] > 0) 
96    pW.println("<td><center>"+an[3] + "/" + an[3] * 100 / an[0] 
97          + "</center></td>"); 
98 else 
99    pW.println("<td><center>"+an[3] + "/0</center></td>"); 
100 pW.println("</tr>"); 
101 } 
102 } 

起实际作用的 servlet

已经提到过 TestTeam servlet,现在应该介绍它了。因为 servlet 变得更长更复杂,所以我无法在这里包含整个代码,但是它包含在 .zip 文件中。在这里包含了我想描述的主要部分。大多数未包含的片断都是重复的。这就是我将说明的例子以及原因。

正如先前提到的,我将描述这个 servlet 的各个方面,然后留给您去彻底地阅读和了解它。第一点要注意的是第 15 行:private DBaccess access;,它告诉我们涉及到了另一个类 DBaccess。这个类是真正的起实际作用的类,因为它执行所有数据库查询并处理任何更新。源代码包含在 .zip 文件中但不在这里,因为要描述的内容太多。下面是安装这个代码以在 WebSphere 中执行的步骤。

当第一次装入 servlet,第一次实例化时,调用 servlet 的 init() 方法,如第 20 行所示,public void init() { access = new DBaccess(getServletContext());}。这创建了 DBaccess 对象,它在 servlet 的生命期内保持活动。可以在第 27 行:access.startAction(); 看见 DBaccess 类的第一次使用,我们可以在其中看见 startAction 方法的调用。这个方法简单地通过调用 ConnectionPool 方法连接到数据库。在后面的第 32-43 行中,语句 access.getLastDateAndDriver(); 再次调用 DBaccess 类。在这个例子中,它正在对数据库进行查询以检索上次数据库更新的日期和驱动程序名称。接下来的几行显示了如何对查询返回的结果进行查错,然后进行格式化以便显示。将生成的 HTML 标记和文本传递到 pW — printWriter 对象。这个对象用于将文本和标记传递到浏览器以便显示。输出类似于 图 11。

第 50-59 行显示了表单的构造以及显示在表中的列名。表位于表单中。表的第一列是按钮列表。每个平台(即 Windows、AIX、Solaris 等)有一个按钮。其余的列包含该平台的总结数据。通过选择一个按钮,可以将您带到一个新的页面 Platform.jsp,它是作为 FORM 标记上的 ACTION 参数列出的。这个 JSP 显示了那个平台的详细测试结果。类似地,还有一节显示了产品而不是平台的总结测试结果。由于这一节与平台代码非常相似,所以这里已经从 servlet 中除去以节省空间。有一点区别是:产品表单的 ACTION 参数指向 product.jsp。这两个级联的 JSP,每一个都有一个相应的 sevlet:Platform.java 和 Product.java。这些 servlet 通过调用 JSP 来完成所显示表的填充工作。下面描述了 Product.java。因为 Platform.java 与 Product.java 非常相似,所以没有进行描述。

第 60-65 行包含语句 putPlatRow(access, pW, "Windows", astring[1]);,它是在这个 servlet 中对 putPlatRow 方法的一系列调用。还显示了 putPlatRow 方法。这个方法用于对上面提到的表中列的总结数据进行查询和格式化。有一个类似的方法 putProdRow(...),它完成的功能相同,但是它基于产品而不是平台。每个调用传递一个不同平台,查询基于该平台的测试数据。 putPlatRow 方法通过 dBaccess.queryTotalsByPlatformDriver(string1, string2); 调用从数据库获取数据,如代码样本所示。DBaccess 类方法 queryTotalsByPlatform 执行查询,然后将数据作为整数数组返回,其中每个整数对应于显示表中的一列。类似地,对于产品表,有 queryTotalsByProductDriver 方法。

最后几行接收由 queryTotalsByPlatformDriver 调用返回的值数组,然后对它们进行格式化以便显示。请注意额外的逻辑,该逻辑处理对于特定方案没有测试用例的情况,即,测试用例数为零。以我的数学知识,我记得除数最好不为零。putProdRow 方法存在相似的逻辑,该逻辑从 queryTotalsByProductDriver 方法获取其结果数组。

既然了解了这个 servlet 是什么,就需要将它和 TestResults.jsp 添加到 WebSphere Web 服务器。即使没有准备好 Platform.jsp 和 Product.jsp,我们仍然可以集成 TestResults.jsp 和 TestTeamCl servlet。因为在安装第一个 JSP 和 servlet 时完成了大部分工作,所以这些步骤非常简单。我们只需要遵循上面安装 TeamStruct JSP 和 TeamStructCl servlet 所完成的相同步骤。除了更改名称外,步骤完全相同。我们还遵循完全相同的步骤,从 AAT 保存 .ear 文件,将它装入 Admin Console,重新生成 HTTP 服务器,重新启动 HTTP 服务器,然后通过执行下列步骤来测试它:

启动浏览器,或者如果它已在运行,则用它访问 http://your-machine-name/testTeam/Web/TestTeam.html,其中您可以选择 TestResults 按钮来调用 TestResults.jsp 从而调用 TestTeamCl servlet。

图 11:TestTeamCl servlet 的部分输出和标题

Last Update2001/04/20 15:32:22Latest Debug/OLT Driver20010411b

如果您选择 Platform 和 Product 表中任何按钮,将显示错误。这是因为我们还没有为 Platform 和 Product JSP 编写这些按钮要调用的代码,也没有编写相应的 servlet。因此,这就是下一步。

Tags:编写 操作 DB

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接