为 WebSphere Portal 4.2 开发 Struts 应用程序

级别: 初级

Tim Hanis (hanistt@us.ibm.com), WebSphere Portal Development, IBM 罗利(Raleigh)实验室
Jim Bonanno (bonanno@us.ibm.com), WebSphere Portal Development, IBM 罗利(Raleigh)实验室
Lisa Tomita (tomato@us.ibm.com), WebSphere Portal Development, IBM 罗利(Raleigh)实验室

2003 年 6 月 01 日

在本文中,我们将讨论 Web 应用程序的实现(先把这个应用程序编写成基于 servlet 的 Struts 应用程序,然后作为 portlet 把它部署到 IBM WebSphere Portal)。Struts 是 Apache Jakarta 项目的一部分,它为构建 Web 应用程序提供了很流行的开放源代码框架。

© Copyright International Business Machines Corporation 2003. All rights reserved.

 

引言

在本文中,我们将讨论 Web 应用程序的实现(先把这个应用程序编写成基于 servlet 的 Struts 应用程序,然后把它作为 portlet 部署到 IBM WebSphere® Portal)。Struts 是 Apache Jakarta 项目的一部分,它为构建 Web 应用程序提供了很流行的开放源代码框架。WebSphere Portal V4.2 提供 Struts Portlet 框架,这一框架支持把 Struts 应用程序作为 portlet 来部署。Struts Portlet 框架还在 Struts 应用程序中提供门户方式支持和设备支持。

对于那些看过有关 把状态模式应用到 WebSphere Portal portlet 的文章的读者来说,本文将说明如何用常见的设计思路和 Struts 框架来开发和部署相同的示例应用程序。与其它文章相似,我们将在这里开发的应用程序维护着特定于登录用户的联系人(通讯簿条目)列表。联系人列表在数据库中持续(或在内存中“持续”),并允许在列表中查看联系人或单独地、更详细地查看联系人。编辑功能使您能够添加、删除或修改联系人。

我们将先实现成 Struts 应用程序而不考虑门户环境。但是,本文的重点不是构建 Struts 应用程序。对于那些不熟悉使用 Struts 来开发 Web 应用程序的读者来说,本文提供了足够的信息以使您掌握基础知识,但本文不是使用 Struts 的教程。在开发这个应用程序时将使用包括在 Struts Portlet 框架(在 WebSphere Portal V4.2 中它是 Struts 1.1 Beta 2)中的 Jakarta Struts 框架。在完成了初步的开发之后,我们将作一些修改以便作为 portlet 来部署 Struts 应用程序。

在本文中讨论的应用程序的开发或部署中用到了以下产品:

  • WebSphere Portal V4.2
  • WebSphere Application Server V4
  • 用于联系人条目的持久性的数据库(可选)
  • WebSphere Studio V4.03(可选)





回页首


 

示例应用程序

我们的示例应用程序将只实现对一组持久数据的标准的创建/读取/更新/删除(Create/Read/Update/Delete,CRUD)操作。这个示例应用程序为给定的用户维护联系人列表(简单的通讯簿)。这个应用程序让用户单独地或在列表中查看联系人条目。

在可视的透视图中,联系人列表应用程序的实现可以有以下视图或页面:

视图 显示
登录用户登录视图
主要联系人列表并带有选择一个联系人以了解更多信息的选项
详细信息选中的联系人的详细信息
主编辑联系人列表并带有添加、删除或修改的选项
添加联系人可输入新联系人的信息的表单视图
修改联系人显示现有的联系人元素数据并允许更新的表单视图

在这一方案中,您没有删除条目的显式页面。操作情况是这样的:用户选择一个联系人条目并从主编辑页面中删除。没有确认页面或成功执行页面。进行条目删除的处理并刷新主编辑页面。如果出现错误,那么将显示适当的消息。





回页首


 

应用程序设计

在设计应用程序时,请考虑构成应用程序的操作和视图。请把操作看作您需要为 portlet 实现的某个用户级别的功能或行为。例如,您可能需要添加联系人的操作或显示某个视图的操作。视图是用户操作完成后应用程序的表示。例如,添加新联系人的操作可能导致 portlet 视图处于编辑方式(显示主要的联系人列表)。

还有,请考虑应用程序的外观如何。在这个示例中,您可能需要列出您创建的联系人的主要视图页面。这个页面应当让用户选择其中一个联系人从而获取有关这个人的更多的详细信息。

因为我们要求每个用户的联系人列表应当是独特的,所以我们将把登录功能作为应用程序的一部分来实现。登录认证是不重要的,登录“成功”时我们将 User 对象放置在会话中以表示该用户已登录。当我们转到门户环境时,我们只需使用门户为我们建立的 User 对象而不必使用我们自己的对象。我们只需从 User 对象中获取唯一的标识(例如用户标识)。

您还应当能够在列表中添加、删除和修改联系人。您将需要主编辑页面,这个页面也列出联系人,但还让您删除或修改选中的联系人。为了删除,您只需留在相同的主编辑页面上,使联系人列表被正确地刷新而不必实现另一个视图。为了修改联系人,显示详细信息页面,您可在这个页面上更新选中的联系人条目的任何属性。当您完成修改时可以返回主编辑页面。类似地,为了在主要页面上新建联系人,您可以到详细信息页面上输入并保存新联系人条目属性,然后再次返回主编辑页面。

您可以确定这个应用程序可用的状态转换。管理转换的方式是应用适当的操作,这将导致应用程序生成特定的视图。在图 1 中,椭圆表示视图(JSP),长方形表示操作。图中没有显示某些取消操作转换(从添加联系人视图和修改联系人视图返回主编辑视图)。


图 1. 转换图
转换图




回页首


 

应用程序实现

根据我们的设计,我们需要实现八个操作类:

  • LoginAction
  • MainViewAction
  • DetailViewAction
  • MainEditAction
  • AddContactAction
  • DeleteContactAction
  • ModifyAction
  • ModifyContactAction。

请注意添加联系人视图实际上只是从主编辑视图到这个 JSP 的直接转发。因为在处理这个视图之前无需任何业务逻辑,所以我们只需直接调用添加联系人 JSP(把它配置成全局转发而不是操作)。

 

设置开发环境

您可以使用 WebSphere Studio Application Developer 来创建 Struts 应用程序。为了这样做:

  1. 在 Application Developer 中创建新的 Web 项目。这将设置带有所有所需的 JAR 文件(除了 cm.jar )的构建路径。您可以在项目属性对话框中添加 cm.jar 的变量。
    图 2. 创建 Web 项目
    创建 Web 项目
  2. 下一步,把 PortalStrutsBlank.war 文件(请参阅 下载)导入到项目中(覆盖起初创建项目时添加的 web.xml 文件)。在标准的 WebSphere Portal 4.2 安装中,您将在 <wp_root>\dev\struts\StrutsPortlet 目录中找到 PortalStrutsBlank.war 文件。这个 WAR 文件的导入将为 Jakarta Struts 1.1 Beta 2 和 IBM 的 Struts Portlet 框架把 Struts JAR 文件添加到项目的 lib 目录中(尽管在练习的第一部分中我们只对基于 servlet 的联系人列表应用程序的构建感兴趣)。
  3. 在导入的过程中创建了缺省的 application.properties 文件。这个文件在项目的 source 目录 resources 子目录下。在构建过程中,这个文件将从 source/resources 目录转移到 WEB-INF/classes/resources 目录。
  4. WEB-INF/src/java/resources/application.properties 的导入过程中还创建了新目录。您可以删除这个从 /src/java/resources/application.properties 开始的目录结构,因为它在这里是多余的。
  5. 导入还将带来 portlet.xml 文件,在我们试图把这个应用程序作为 portlet 来运行之前我们不需要 portlet.xml。您可以删除或暂时忽略这个文件。
  6. 删除 lib 目录中的 jdbc2_0-stdext.jar 文件。否则, com.ibm.ejs.cm.JDBC1PhaseRF 可能出现 ClassCastException,因为在这个 JAR 和 j2ee.jar 中有冲突。
  7. 最后,把标记库从 /WEB-INF/ 目录转移到新目录 /WEB-INF/tld/ 。这只是使我们更仔细地组织文件。

您已完成了在 Application Developer 中开发 Struts 应用程序的基本设置。如果您不选用 Application Developer,那么您只需确保以下 JAR 文件在构建路径上(另外还有导入的 Struts JAR 文件)。您可在 <wp_root>\lib\<wp_root>\lib\app 中找到这些文件。

  • WAS_PLUGINDIR/lib/j2ee.jar
  • WAS_PLUGINDIR/lib/webcontainer.jar
  • WAS_PLUGINDIR/lib/ivjejb35.jar
  • WAS_PLUGINDIR/lib/websphere.jar
  • WAS_PLUGINDIR/lib/cm.jar
  • SERVERJDK_PLUGINDIR/jre/lib/rt.jar

在考虑操作类、bean、表单或支持类的实现细节之前,您应当先考虑应用程序配置文件的实现。它们包括 Web 应用程序部署描述符( web.xml )、Struts 配置文件( struts-config.xml )和 Struts 表单验证 xml 文件( validation.xml )。

 

Web 部署描述符:web.xml

提供的缺省的 web.xml 文件是门户 Struts 框架的一部分。在导入 PortalStrutsBlank.war 文件时创建了这个文件,并设置了 Struts 标记库描述符和缺省的欢迎文件。

需对部署描述符作一些特定于应用程序的修改:

  • <display-name> 改为对这个应用程序有意义的名称。
  • <servlet-class> 改为 org.apache.struts.action.ActionServlet 。这将在 Struts 应用程序被转移到门户环境时被改回 com.ibm.wps.portlets.struts.WpsStrutsPortlet
  • <web-app id="WebApp_1862436328"> 必须包含唯一标识。这个缺省标识可用于我们的第一个 Struts 应用程序,但是一般来说,应当总是唯一值。
  • 更新操作 servlet 映射,把 <servlet-name><url-pattern> 的值分别设置为“action”和“do”。
  • web.xml 文件中需要两个初始化参数来支持持久类(持久类包含在下载中): persist_to_dbdatasource 。把 persist_to_db 设为“false”将触发内存中“持久性”代理的使用。把这个值设为“true”将导致使用数据库代理。如果使用后者,请一定设置将被使用的数据源的名称。如果使用了内存中持久性,那么这个值将被忽略。

 

Struts 配置:struts-config.xml

struts-config.xml 文件包含 Struts 框架用于控制、导航和配置设置的应用程序定义。

  • 必须指定所需的表单 bean。我们有两个表单 bean:一个用于登录处理,保存用户标识和密码,另一个用于引用模型对象(联系人元素)。以下代码片段定义了 struts-config.xml 文件中的表单 bean:
<form-beans>   <form-bean name="logonForm" type="com.ibm.aim.view.LoginForm"/>   <form-bean name="contactForm" type="com.ibm.aim.view.ContactForm"/> </form-beans>
 

 

  • 需要修改这个 xml 以支持转换图中标出的操作。有八个指定的操作,下面的代码用我们示例实现中的类名定义了这些操作。我们还要为每个操作指定适当的“转发”设置以指出用于处理请求的视图的 JSP。我们的转换图也指定了这些处理状态:
<action     path="/validatelogin"             type="com.ibm.aim.controller.LoginAction"             name="loginForm"             scope="request"             input="/index.jsp"> </action> <action     path="/mainview"             type="com.ibm.aim.controller.MainViewAction"             name="contactForm"             scope="request"             validate="false" >     <forward             name="success"             path="/WEB-INF/pages/main_view.jsp"/> </action> <action             path="/detailview"             type="com.ibm.aim.controller.DetailViewAction"             name="contactForm"             scope="request"             validate="false" >             <forward                     name="detailviewpage"                     path="/WEB-INF/pages/detail_view.jsp"/> </action> <action     path="/mainedit"             type="com.ibm.aim.controller.MainEditAction">             <forward                     name="maineditpage"                     path="/WEB-INF/pages/main_edit.jsp"/> </action> <action     path="/modify"             type="com.ibm.aim.controller.ModifyAction"             name="contactForm"             scope="request"             validate="false" >             <forward                     name="editcontactpage"                     path="/WEB-INF/pages/edit_contact.jsp"/>             <forward                     name="deletecontact"                     path="/deletecontact.do"/> </action> <action     path="/modifycontact"             type="com.ibm.aim.controller.ModifyContactAction"             name="contactForm"             scope="request"             validate="false" >             <forward                     name="mainedit"                     path="/mainedit.do"/> </action> <action     path="/deletecontact"             type="com.ibm.aim.controller.DeleteContactAction"             name="contactForm"             scope="request"             validate="false" >             <forward                     name="maineditpage"                     path="/WEB-INF/pages/main_edit.jsp"/> </action> <action     path="/addcontact"             type="com.ibm.aim.controller.AddContactAction"             name="contactForm"             scope="request"             validate="false" >             <forward                     name="addcontactpage"                     path="/WEB-INF/pages/add_contact.jsp"/> </action>
 

 

  • 我们还要指定全局转发、消息资源文件和验证 xml 文件引用:
    • 全局转发使逻辑名与 JSP 或操作的引用的 URI 关联。通过使用全局转发,只要逻辑引用名不变,我们就不必因为 URI 有所变动而修改我们的代码。
    • message-resources 参数的值引用缺省消息资源束。
    • validation.xml 文件定义了登录视图的验证要求。
<global-forwards>  <forward name="login" path="/index.jsp"/>  <forward name="addcontactpage" path="/WEB-INF/pages/add_contact.jsp"/>  <forward name="mainedit" path="/mainedit.do" />  <forward name="mainmenu" path="/mainmenu.do" /> </global-forwards> <message-resources parameter="resources.application"/> <plug-in className="org.apache.struts.validator.ValidatorPlugIn">   <set-property property="pathnames"                    value="/WEB-INF/validator-rules.xml,                           /WEB-INF/validation.xml"/> </plug-in>
 


 

Struts 验证:validation.xml

我们将使用 Struts 提供的输入验证以确保用户在试图登录到应用程序时确实真正地输入了用户标识和密码。验证只是确保用户为两个值输入了某个字符串;实际的认证在我们专为此目的编写的 bean 中进行。(当应用程序被转移到门户环境时将使用门户用户信息,特定于应用程序的登录处理将被删除。)

对于我们的输入验证,请使用以下代码来修改 validation.xml 。验证需要表单名称、域和验证要求:

  • 表单: logonForm
  • 域: userNamepassword ,两个都要。还有定义了标签名 loginForm.usernameloginForm.password 的资源属性文件。
  • 验证要求:用户在登录表单上输入用户标识和密码。
<form-validation>    <formset>      <form name="logonForm">            <field property="userName"                   depends="required">            <arg0 key="loginForm.username"/>            </field>            <field property="password"                   depends="required">            <arg0 key="loginForm.password"/>            </field>       </form>    </formset> </form-validation>
 


 

操作类的实现

接下来我们将实现操作类。对于在状态转换图中标出的并在 struts-config.xml 中定义的每个操作,我们需要一个继承 org.apache.struts.action.Action 的实现。

清单 1 显示了其中一个操作类的代码。DeleteContactAction 类实现了删除联系人的函数。操作类继承的抽象类也已被创建以保存所有的操作类实现所需的共同代码。例如,我们在那里添加了在执行这个函数之前验证用户已登录的代码。

清单 1. DeleteContactAction 类

public class DeleteContactAction extends PostLoginAbstractAction {         public ActionForward performAction(ActionMapping mapping, ActionForm form,                 UserBean user, HttpServletRequest request, HttpServletResponse response)                 throws Exception {                 // Get the user ID and selected oid                 String user ID = user.getUserName();                 ContactForm contactForm = (ContactForm) form;                 String oid = contactForm.getSelectedContact();                 // Delete the contact                 ContactHelper contactHelper = ContactHelper.getInstance();                 contactHelper.deleteContact(user ID, oid);                 // Render the main edit page                 return (mapping.findForward("mainedit"));         } }
 

 

抽象操作类继承了 org.apache.struts.action.Action 并实现了 execute 方法。这个实现确保我们已登录,然后调用被调的 Action 类和 performAction 方法,他们传递的参数是与传给 execute 方法的参数相同,再加上在登录验证过程中检索到的用户 bean。请看清单 2。(当应用程序被转移到门户环境时,登录操作将被删除,并通过修改代码来从 portletRequest 对象中检索 User 对象。到那时,任何访问 User 对象的应用程序代码可改用 WPS User 对象 API。)

清单 2. PostLoginAbstractAction 类

public abstract class PostLoginAbstractAction extends Action {         public ActionForward execute(ActionMapping mapping, ActionForm form,                 HttpServletRequest request, HttpServletResponse response)                 throws Exception {                 // Check for existing session with user key. Go to login if                 // not found.                 UserBean user = null;                 HttpSession session = request.getSession(false);                 if (session != null)                 user = (UserBean) session.getAttribute("user");                 if (user == null)                 return (mapping.findForward("login"));                 // Invoke the action class performAction method                 return performAction(mapping, form, user, request, response);         }         public abstract ActionForward performAction(ActionMapping mapping, ActionForm form,                 UserBean user, HttpServletRequest request, HttpServletResponse response)                 throws Exception; }
 

 

其余的操作类实现很相似。如 DeleteContactAction 类所示(清单 1),一些操作类将使用持久类的服务。再说一次,提供的持久函数包含在下载实现中。

ContactListBroker 接口(清单 3)定义了应用程序处理联系人列表所需的函数。(如果您想了解特定的代理是如何实现这个函数的,请查看 下载中的代码。)

清单 3. ContactListBroker 接口

public interface ContactListBroker {         /**          * Get the Contact information given a contact number          * @param owner java.lang.String          * @param contactOID java.lang.String          * @return ContactForm         */         public ContactForm getContact(String owner, String contactOID) throws AIMException;         /**          * Create a Contact          * @param ContactForm          */         public void saveContact(ContactForm contactForm) throws AIMException;         /**          * Delete a Contact          * @param owner java.lang.String          * @param contactOID java.lang.String          */         public void deleteContact(String owner, String oid) throws AIMException;         /**          * Get the contact list.          * @param owner java.lang.String          * @return List of ContactForm objects          */         public List getContactList(String owner) throws AIMException; }
 


 

应用程序 bean

这个应用程序定义了三个 bean:

  • UserBean:表示登录的用户。在应用程序中,这个 bean 只保存用户标识和密码。
  • ValidateUserBean:负责为登录提供的用户标识和密码的认证处理。在此,这个实现是不重要的,因为任何用户标识和密码都将被接受(仅有的一个例外是“invalid”密码,这是为测试目的提供的)。
  • 最后一个 bean 是帮助程序类,它提供了添加联系人和删除联系人的共同的函数。(本文中没有列出,但可在下载中找到。)

 

Struts 表单 bean

根据 struts-config.xml 文件中的定义,这个应用程序有两个表单 bean 实现,这些实现继承了 org.apache.struts.validator.ValidatorForm 并包含适用于两者的属性(带有存取方法):

  • ContactForm:属性一般映射到 contacts 表中的列。请参阅 设置数据库以了解样本表的定义。
  • LoginForm:属性至少包含用户标识和密码。

 

应用程序资源属性

消息属性文件(它的名称是 application.properties ,位于 resources 目录中)在 struts-config.xml 文件中定义。这个文件包含应用程序所需的两个属性( loginForm.usernameloginForm.password )以及错误消息的标准属性。

 

JavaServer Pages(JSP)文件

我们的应用程序的最后的组件是 JSP 文件。根据转换图以及 struts-config.xml 文件中的定义,我们需要实现五个 JSP(每个 JSP 被用来处理):

  1. 添加联系人页面
  2. 修改联系人页面
  3. 主要视图页面
  4. 主编辑页面
  5. 详细信息视图页面
  6. 登录页面。

为了提供应用程序的登录屏幕,您还需要更新 index.jsp 文件。这个 JSP 使用登录操作和 LoginForm bean。在成功登录之后用户将位于主要视图页面上(图 3),这个页面显示了特定于这个用户的联系人列表。


图 3. 主要列表视图
主要列表视图

清单 4 显示了一些 JSP 文件的关键部分:用于处理主要视图的 JSP,紧随其后的是这个 JSP 的处理内容的示例。这个 JSP 需要包含联系人列表的 bean(bean 的作用域是会话)。定义了几个标准的 Struts 标记库以便在这个 JSP 中使用,struts-html 标记库中的 rewrite 标记被用来链接到适当的级联样式表。同样的库中的 form 标记也被用来定义与这个视图关联的操作。在这种情况下,当用户选择处理列表中的联系人时,处理应当继续进行到 detailview 操作并把选中的联系人作为参数与请求表单数据一起被传递。另一个表单也被添加到这个视图,使用户可以选择进入主编辑视图。

清单 4. 主要视图 JSP

... <jsp:useBean id="contactList" class="java.util.List" scope="request" /> <%@ taglib uri="/WEB-INF/tld/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/tld/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/tld/struts-logic.tld" prefix="logic" %> <LINK href="<html:rewrite page='/theme/Styles.css'/>" rel="stylesheet" type="text/css"> <LINK href="<html:rewrite page='/theme/Master.css'/>" rel="stylesheet" type="text/css"> ... <table border="0" width="95%" align="center" cellspacing="0" cellpadding="0" >   ...   <tbody>   <html:form method="post" action="/detailview">     <input type="hidden" name="selectedContact">     <logic:iterate name="contactList" id="aContact">     <tr>       <td valign="top" align="left">         <a href="javascript:document.contactForm.selectedContact.value=           '<bean:write name="aContact" property="oid"/>';document.contactForm.submit()">           <bean:write name="aContact" property="firstName"/>           <bean:write name="aContact" property="lastName"/>         </a>       </td>       <td class="wpsPortletSmText" valign="top" align="left">         <bean:write name="aContact" property="company"/>       </td>       <td class="wpsPortletSmText" valign="top" align="left">         <bean:write name="aContact" property="email"/>       </td>       <td class="wpsPortletSmText" valign="top" align="left">         <bean:write name="aContact" property="mobilePhone"/>       </td>     </tr>   </logic:iterate>   </html:form>     <tr>       <td colspan="4">         <html:link forward="mainedit">         <html:img page="/images/task_edit.gif" title="Edit" border="0"/>Edit</html:link>       </td>     </tr>   </tbody>   </table> ...
 


 

设置数据库

创建的应用程序有两个数据持久选项:一个是数据库代理实现,另一个是内存中实现。为了测试目的,您可能想只用内存中版本,因为它使您不必完成下面的数据库设置步骤;但是,每次应用程序服务器重新启动时数据将丢失。您可以通过在 Web 部署描述符文件 web.xml 中设置配置参数来选择代理类型。

  • 为了使应用程序数据在数据库中持久,您需要创建数据库表以保存联系人列表数据。为了创建表,请在命令行中运行以下 SQL 命令(替代您所选择的模式名,但是表名称是固定的)。您可以为这个表创建新数据库,或者把它添加到现有的数据库。如果您使用 DB2,请在建立了适当的数据库的连接之后把以下命令复制到命令中心,然后在命令中心运行它:
CREATE TABLE "DB2ADMIN"."CONTACTS" ("OWNER" VARCHAR(64) NOT NULL, "OID" VARCHAR(64) NOT NULL PRIMARY KEY, "FIRST_NAME" VARCHAR(32) NOT NULL, "LAST_NAME" VARCHAR(32) NOT NULL , "EMAIL" VARCHAR(128) NOT NULL, "TITLE" VARCHAR(64), "COMPANY" VARCHAR(64), "BUS_PHONE" VARCHAR(32), "MOBILE_PHONE" VARCHAR(32), "FAX_PHONE" VARCHAR(32), "WEB" VARCHAR(128), "ADDRESS1" VARCHAR(32), "ADDRESS2" VARCHAR(32), "CITY" VARCHAR(32), "STATE" VARCHAR(2), "ZIP" VARCHAR(10), "COUNTRY" VARCHAR(32) )
 

 

  • 把条目添加到联系人列表的表中以便于您在开发 portlet 的过程中测试它。为了创建新条目,请执行以下 SQL 命令。如果您在登录到门户时使用的用户标识不是测试标识 wpsadmin ,请务必在 SQL 语句中用这个用户标识来替换 wpsadmin
insert into contacts (owner, oid, first_name, last_name, email, company, mobile_phone) values ('wpsadmin', '01', 'Tim', 'Hanis', 'hanistt@us.ibm.com', 'IBM', '919-247-4098')
 

 

  • 请在 WebSphere Application Server 中为您创建的 Contacts 表所在的数据库创建数据源。在应用程序服务器管理控制台中(图 4),选择 Resources => JDBC Providers,然后展开适当的 JDBC 驱动程序。在 Data Sources上单击鼠标右键,然后选择 New
    • 输入数据源名称作为 JNDI name 的值。
    • 输入数据库名、用户和密码值。
    • 测试连接。


图 4. 在 WebSphere Application Server 中创建数据源
在 WebSphere Application Server 中创建数据源

  • 如果您打算使用 WebSphere Studio Application Developer 来测试和调试 Struts 应用程序,请在 Application Developer 中创建同样的数据库的数据源。在 Application Developer 服务器透视图中(图 5),编辑 WebSphere Administrative Domain( server-cfg.xml 文件),选择编辑窗格上的 datasources选项卡,选择适当的 JDBC 驱动程序,添加数据源,提供适当的属性值。


图 5. 在 WebSphere Studio Application Developer 中创建数据源
在 WebSphere Studio Application Developer 中创建数据源

 

实现类总结

下面的表列出了为我们的示例应用程序实现的 Java 类。其它实现当然可能有所不同,但是这定义了 下载中完整实现的类以及每个类的简要描述。

描述
com.ibm.aim.beansContactHelper用于调用联系人的持久管理函数的帮助程序类
UserBean表示登录的用户
ValidateUserBean验证用户标识和密码
com.ibm.aim.controllerAddContactAction处理添加联系人的请求
DeleteContactAction处理删除联系人的请求
DetailViewAction处理显示详细的联系人视图的请求
ModifyAction处理修改联系人的请求
ModifyContactAction处理保存编辑的联系人修改的请求
MainEditAction处理显示主编辑视图的请求
MainViewAction处理显示主要的联系人列表视图的请求
PostLoginAbstractAction用于登录后操作的抽象类
LoginAction处理登录请求
com.ibm.aim.viewContactForm表示联系人的 Struts 表单对象
LoginForm表示登录请求的 Struts 表单对象
com.ibm.aim.persistenceBrokerFactory创建具体的代理实例
ContactListBroker持久类接口
DbAbstractBroker数据库代理的共同函数的抽象类
DbBrokerImpl数据库代理实现继承了 DbAbstractBroker 并实现了 ContactListBroker
DbBrokerParms定义访问数据库所需的配置参数
DbBrokerParmsImpl访问数据库所需的配置参数的实现
MemoryBrokerImpl内存代理实现实现了 ContactListBroker
com.ibm.aim.utilitiesAIMException基本异常类
AIMLoginException登录失败的异常
AIMWrapperException包装另一个(“下面的”)异常的 AIMException
RetryException用于数据库失败的异常(表示需要重试)

 

完成实现并测试

您现在应当能够完成实现并测试结果。(您也可以从 下载中获取完成的 Struts 应用程序。)为了在 Application Developer 中测试实现,您只需选择导航程序窗格中的 index.jsp 文件,用鼠标右键单击,选择 Run on Server。这将在 Application Developer 中创建服务器实例并在 Web 浏览器中启动 index.jsp 。如果您使用这个方法来创建新的服务器实例并且使用数据库持久性管理器,那么您需要完成在 Application Developer 中定义数据源的步骤(图 5)以使这个应用程序能够成功运行。

在阅读下一部分(下一部分描述了把 Struts 应用程序作为 portlet 来运行的步骤)之前,请务必成功地完成并测试示例应用程序。





回页首


 

WebSphere Portal Struts Portlet 框架

前面已提到,Struts Portlet 框架是随 WebSphere Portal V4.2 一起提供的基本产品的组件。该框架支持把 Struts WAR 文件作为 portlet 部署到 WebSphere Portal 4.2,也在基于 Struts 的应用程序中提供门户方式支持和设备支持。

在 WebSphere Portal 4.2 中,被支持的 Struts 框架是 Struts 1.1 Beta 2。在标准的安装中,您可在 <wp_root>\dev\struts\ 目录中找到 Struts 框架。

如果您想了解有关 Struts Portlet 框架的使用的更多信息和限制,请访问 WebSphere Portal 4.2 信息中心。在信息中心主页上,选择 Developing portlets => Struts Portlet Framework





回页首


 

在 WebSphere Portal 中运行所需的修改

我们不必修改 Java 代码就可在门户环境中运行联系人列表 Struts 应用程序。所有的操作、表单 bean、应用程序 bean、持久性和实用程序类都不需要修改。但是,我们需要修改一些应用程序配置文件。下面将讨论这些修改。

 

使用 Struts 模块来支持门户方式

Struts 1.1 已把应用程序分成多个模块的支持构建到框架中。在使用模块时,应用程序的配置信息和目录结构是分开的,所以现在我们不用整个应用程序的单个 struts-config.xml 文件而改用多个控制文件以及分开的目录结构(由应用程序 URI 中与模块相关的部分来标识)。

Struts Portlet 框架利用模块支持来提供 Struts 配置的方式和设备(标记)区分。为了支持方式和设备类型区分,可在 web.xml 中指定两条路径:

  • 第一条是 搜索路径,用来确定使用哪个模块(和 struts-config.xml 文件)。它还确定了定位 JSP 的基本目录。以下初始化参数设置将把搜索路径设为在搜索模块时考虑标记名和方式:
    <init-param>   <param-name>SubApplicationSearchPath</param-name>   <param-value>markupName, mode</param-value> </init-param>
     

  • 第二条路径是 包括路径,用来在搜索中包括常见的 JSP 文件。根据路径设置,搜索从最限定的开始,一直到最不限定的。当第一个文件匹配被找到时搜索就完成了:
    <init-param>   <param-name>IncludesSearchPath</param-name>   <param-value>locale</param-value> </init-param>
     

SubApplicationSearchPath 和 IncludesSearchPath 都是 Struts Portlet 框架定义的初始化参数。

 

Web 部署描述符:web.xml

为了把 Struts 应用程序作为 portlet 来运行,我们需要修改现有的 web.xml 文件:

  • 把上面指定的两个初始化参数(SubApplicationSearchPath 和 IncludesSearchPath)添加到这个部署描述符中。
  • <servlet-class> 改成原来的 com.ibm.wps.portlets.struts.WpsStrutsPortlet
  • 修改 servlet 映射。我们需要指定 portlet 的 servlet URL 映射,所以修改 servlet 映射以使用以下路径前缀 servlet 映射:
    <servlet-mapping id="Unique_ServletMapping">   <servlet-name>Struts</servlet-name>   <url-pattern>/Struts/*</url-pattern> </servlet-mapping>
     

  • 当然,正常的 Struts 应用程序需要 servlet 映射来使路径与操作关联。为了处理这个,Struts Portlet 框架使用需被指定为初始化参数的伪 servlet 映射:

    <init-param>
      <param-name>struts-servlet-mapping</param-name>
      <param-value>*.do</param-value>
    </init-param>

  • 添加以下初始化参数。我们将为我们的应用程序创建三个模块:视图、编辑和帮助。这些模块与设备类型 html 关联,并被配置成初始化参数 /config/<device>/<mode> ,所以我们已定义:
    • config/html/view
    • config/html/edit
    • config/html/help。

与每个模块定义关联的参数值指出在哪里开始搜索 Struts 配置文件。

清单 5. web.xml 文件修改

<init-param>   <param-name>config/html/view</param-name>   <param-value>/WEB-INF/html/view/struts-config.xml</param-value> </init-param> <init-param>   <param-name>config/html/edit</param-name>   <param-value>/WEB-INF/html/edit/struts-config.xml</param-value> </init-param> <init-param>   <param-name>config/html/help</param-name>   <param-value>/WEB-INF/html/help/struts-config.xml</param-value> </init-param>
 

 

  • 最后,修改欢迎文件列表。Struts Portlet 框架允许每个“设备/方式”的初始视图的指定。指定的方法是在欢迎文件列表中通过指出应用程序前缀来提供每个模块的文件(一般是 HTML 或 JSP):
<welcome-file-list>   <welcome-file>html/view/index.jsp</welcome-file>   <welcome-file>html/help/index.jsp</welcome-file>   <welcome-file>html/edit/index.jsp</welcome-file> </welcome-file-list>
 


 

Portlet 部署描述符:portlet.xml

为了把 Struts 应用程序作为 portlet 来运行,我们还需要创建 portlet.xml 文件。请记住 portlet.xml 中定义的 portlet href 属性必须映射到 web.xml 文件中的 servlet 标识。

清单 6. portlet.xml

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE portlet-app-def PUBLIC "-//IBM//DTD Portlet Application 1.1//EN" "portlet_1.1.dtd"> <portlet-app-def>    <portlet-app uid="DCE:b067c2c0-1eba-1211-0000-02884891a5dc:1" major-version="1" minor-version="0">       <portlet-app-name>StrutsContactsWeb application</portlet-app-name>       <portlet id="Portlet_1" href="WEB-IN

http://www-128.ibm.com/developerworks/cn/websphere/techjournal/0303_hanis/hanis.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值