首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Struts,MVC 的一种开放源码实现(4)再访邮件列表样例

Struts,MVC 的一种开放源码实现(4)再访邮件列表样例

再访邮件列表样例下面我们看一下 Struts 是如何解决困扰         join.jsp 的这些问题的。改写后的方案由两个项目组成。第一个项目包含应用程序的逻辑部分,这个应用程序是独立于Web 应用程序的。这个独立层可能是用 EJB技术实现的公共服务层。为了便于说明,我使用 Ant构建进程创建了一个称为         business 的包。有几个原因促使我们使用独立的业务层:      
  • 划分责任
    单独的包使管理人员能够在开发小组内委派责任。这也有助于提高开发人员的责任心。
  • 通用件
    我们设想开发人员将这个包看作一个商业软件。将它放在另外的包中使它更像通用件。这个包可能是通用件,也可能是由组织内部的另一个小组开发的。
  • 避免不必要的构建和单元测试。
    分开的构建进程有助于避免不必要的构建和单元测试。
  • 使用接口开发
    在进行开发和避免不必要的耦合时,它有助于从接口的观点来思考问题。这是极重要的一个方面。当开发您自己的业务包时,这些业务类不应该关心到底是Web应用程序执行调用,还是独立应用程序执行调用。因此,应该避免在业务逻辑层使用对servlet API 或 Struts API 调用的任何引用。
  • 稳定性
    并不是每个组织都每天、每周甚至每月进行检修。因此,在进行开发时,稳定的接口点是重要的。不能因为业务包处于变迁阶段就认为Web 项目也应该处于变迁阶段。
业务构建注释我用 Ant 构建项目,并用 JUnit 运行单元测试。business.zip包含构建业务项目所需的一切,当然 Ant 和 JUnit除外。这个包脚本将构建类,运行单元测试,创建 Java 文档和 jar文件,最后将所有这些内容压缩到一个 zip 文件中发送给客户。只要对         build.xml 作一些修改,您就可以将它部署到其他平台上。         Business.jar 位于 Web 的下载部分,因此,您并非必须下载并构建这个业务包。      
Web 项目第二个项目是用 Struts 开发的一个 Web 应用程序。您将需要一个符合 JSP1.1 和 Servlet 2.2 规范的容器。最快的入门方法是下载并安装 Tomcat3.2(请参阅  )。直到有 Struts 的1.0 发行版之前,我建议您从 Jakarta 项目获得最新的版本(请参阅  )。这对我来说是个大问题,我不能确保我的Web 项目样例能与您下载的 Struts 一起工作。Struts仍在不断变化,所以我不得不经常更新我的项目。在本项目中,我使用的是jakarta-struts-20010105.zip。图 8 显示了此 Web项目的结构。如果您已安装了 Ant,则运行这个版本将创建一个称为         joinStruts.war 的 war文件,您随时可以部署这个文件。      
图 8. Web 项目的结构清单 4 显示了转换后的 JSP 文件,称为         joinMVC.jsp 。这个文件从最初的 50 行变为 19 行,并且现在不含任何 Java 代码。从网页设计人员的角度来看,这是个巨大的改进。      
清单 4.         joinMVC.jsp -- 再访简单的 JSP      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %>
<%@ taglib uri="/WEB-INF/struts-form.tld" prefix="form" %>
<html>
<head>
<title><struts:message key="join.title"/></title>
</head>
<body bgcolor="white">
<form:errors/>
<h3>Enter your email to join the group</h3>
<form:form action="join.do" focus="email" >
    <form:text   property="email" size="30" maxlength="30"/>
    <form:submit property="submit" value="Submit"/>
</form:form>
</body>
</html>




网页的变化下面是使用 Struts 标记库之后所发生变化的列表:
  • Import         
    1
    <%@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %>





    用于 Java 代码的           <%@page import? 已被替换为用于Struts 标记库的           <%@ taglib uri? 。
  • 文本         
    1
    <struts:message key="join.title"/>





    资源属性文件包含           join.title 的文本。在本例中,ApplicationResources属性文件包含这个名值对。这使字符串更易于查看和国际化。
  • 错误         
    1
    <form:errors/>




    ActionServlet 或           ActionForm 构建要显示的错误消息。这些错误消息也可以包含在属性文件中。ApplicationResources也提供了一种格式化错误的方法,即设置           error.header 和           error.footer 。
  • HTML 表单         
    1
    <form:form action="join.do" focus="email" >




    • JSP               <form> 标记和属性替代了 HTML               <form> 标记和属性。               <formaction="join.jsp" name="join"> 已更改为               <form:form action="join.do" focus="email"> 。
    • HTML               <input> 标记已替换为               <form:text/> 。
    • HTML               <submit> 标记已替换为               <form:submit/> 。
模型 -- 会话状态JoinForm 扩展了         ActionForm 并包含表单数据。本例中的表单数据只有电子邮件地址。我已为电子邮件地址添加了一个写方法和读方法,以供框架访问。为了便于说明,我重写了         validate() 方法,并使用了 Struts 的跟踪功能。Struts将创建         JoinForm 并设置状态信息。      
模型 -- 业务逻辑如前所述,         Action 是控制器和实际业务对象之间的接口。         JoinAction 包装了对         business.jar 的调用,这些调用最初在         join.jsp 文件中。         JoinAction 的         perform() 方法在清单 5 中列表。      
清单 5. - JoinAction.perform()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public ActionForward perform(ActionMapping mapping,
                             ActionForm form,
                             HttpServletRequest request,
                             HttpServletResponse response)
                             throws IOException, ServletException {
    // 抽取我们将会用到的属性和参数
    JoinForm joinForm = (JoinForm) form;
    String email = joinForm.getEmail();
    ActionErrors errors = new ActionErrors();
    // 存储输入....
    try {
        business.db.MailingList.AddEmail(email);
    } catch (Exception e) {
        // 记录日志,打印栈
        // 将错误回显给用户
        errors.add("email",new ActionError("error.mailing.db.add"));
    }
    // 如需任何消息,请将指定的错误消息键保存到
    //  HTTP 请求中,以供 <struts:errors> 标记使用。
    if (!errors.empty()) {
        saveErrors(request, errors);
        // 返回到初始表单
        return (new ActionForward(mapping.getInput()));
    }
    // 将控制权转交给 Action.xml 中指定的 'success' URI
    return (mapping.findForward("success"));
}




注:         perform() 返回一个称为         ActionForward 的类,该类通知控制器下一步该执行什么操作。在本例中,我使用从控制器传入的映射来决定下一步的操作。      
控制器我已修改了 JSP文件,并创建了两个新类:一个类用来包含表单数据,一个类用来调用业务包。最后,我通过修改配置文件         struts-config.xml 将它们整合起来。清单 6显示了我添加的 action 元素,这个元素用来控制         joinMVC.jsp 的流程。      
清单 6. Action 配置
1
2
3
4
5
6
7
8
<action  path="/join"
         name="joinForm"
         type="web.mailinglist.JoinAction"
        scope="request"
        input="/joinMVC.jsp"
     validate="true">
    <forward  name="success"  path="/welcome.html"/>
</action>




action 元素描述了从请求路径到相应的 Action 类的映射,应该用这些类来处理来自这个路径的请求。每个请求类型都应该有相应的         action 元素,用来描述如何处理该请求。对于 join 请求:      
  • joinForm 用来容纳表单数据。
  • 因为 validate 被标记为 true,所以           joinForm 将试图进行自我验证。
  • web.mailinglist.JoinAction 是用来处理对这个映射的请求的 action 类。
  • 如果一切顺利,该请求将转到           welcome.jsp 。
  • 如果出现业务逻辑故障,流程将返回到           joinMVC.jsp ,这是最初发出请求的网页。为什么会这样呢?在清单6 的 action 元素中,有一个称为           input 的属性,其值为           "/joinMVC.jsp" 。在我的           JoinAction.perform() (如清单 5所示)中,如果业务逻辑失败,           perform() 就返回一个           ActionForward ,并以           mapping.getInput() 作为参数。本例中的           getInput() 是           "/joinMVC.jsp" 。如果业务逻辑失败,它将返回到           joinMVC.jsp ,这是最初发出请求的网页。
返回列表