开发最佳实践:在Web应用开发中优化Struts框架

摘自:http://developer.51cto.com/art/201004/195352.htm

本文向您讲解了如何使用灵活的Struts框架调节Web应用程序开发。这里向您展示了一些最佳实践,您可以遵循这些实践来优化这个成熟的开源框架。此外,您还可以学习使用一些十分有价值的标准Struts组件,包括 ActionForm、Action 类和 ActionErrors。

AD:
2013大数据全球技术峰会低价抢票中

Struts是一种开源框架,可用来构建Web应用程序,它基于流行的Model-View-Controller (MVC2) 设计范型。该框架构建在一些标准的技术之上,比如Java Servlets、JavaBeans、ResourceBundles和XML,并且可提供灵活和可扩展的组件。

关于Struts更多内容,请参阅:Struts框架应用专题

Struts以ActionServlet的形式实现了Controller层,并建议使用JSP标记库构建View层。Struts 通过Action类提供了围绕Model层的包装器。图1展示了基于Model-View-Controller设计的Struts框架。

基于Model-View-Controller设计的Struts框架 图1.Struts和MVC

Struts 组件概览

首先,我们在最佳实践上下文中解释 Struts 组件,以及它们在 Web 应用程序开发中所起的作用。

Action

应用程序的每个 Action 都会扩展 Struts 的 org.apache.struts.action.Action 类。这些 Action 类为应用程序的 Model 层提供了一个接口,充当围绕业务逻辑的包装器。每个 Action 类都必须向 perform() 方法提供其特定于用例的实现。perform() 方法经常返回类型 ActionForward 的一个值。

ActionForm

应用程序的 ActionForm 扩展了 Struts 的 org.apache.struts.action.ActionForm 类。ActionForm 是一些封装和验证请求参数的简单 JavaBean。要验证请求数据,ActionForm 的 validate() 方法必须给出一个特定于该情况的实现。ActionForm 作为运载工具,向 Action 类提供请求数据。一个 JSP 对象与各自的 ActionForm 对象相结合,构成应用程序的 View 层。在该层,几乎 JSP 对象的每个表单字段都映射到相应的 ActionForm 的属性。

JSP 定制标记库

JSP 定制标记库是用标记表示的一组行为的集合。这是 JSP Specification 1.1 的一个强大特性;它将其他应用程序层的表示区别了开来。这些库易于使用,而且可以以一种类似 XML 的方式来读取。只要尽量少地在其中使用 Java scriptlet,就可以轻松维护 JSP 组件。Struts 提供的 JSP 标记包括 HTML、逻辑和 bean 标记。

ActionErrors

可以使用 ActionError 来支持异常处理。ActionError 捕捉应用程序异常,并将其传送给 View 层。每个异常都是一个 ActionError 实例的集合。ActionError 可以封装错误消息,而 Presentation 层中的 </html:errors> 可以呈现 ActionError 集合内的所有错误消息。

最佳实践 1. 跨多个 ActionForm 重用数据

熟悉了 Struts 组件之后,就可以继续学习如何充分利用这一框架。首先,Struts 建议将每个 JSP 对象与一个 ActionForm 相关联,后者可以封装屏幕上显示的数据。可以通过 ActionForm 内的附加方法来访问 JSP 对象内的表单数据。清单 1 展示了 ActionForm 标记在 View 层中的传统方法。

  1. 清单 1. 使用 ActionForm
  2. <html:formaction="/bp1">
  3. <html:textproperty="attrib1"/>
  4. </html:form>

这个ActionForm被称为 “BP1AForm”,它包括属性attrib1及其getter和setter方法。在配置文件struts-config.xml中,行为 “/bp1” 通过name属性映射到 bp1AForm。这有助于在JSP中显示数据。要实现这一最佳实践,Struts 建议您进行以下两个操作:

创建一个 JavaBean(BP1BForm),且其属性是 BP1AForm 属性的子集,还要创建这些属性的 getter 和 setter 方法。通过将这个 bean 与 BP1AForm 关联,用 bean BP1BForm 的属性替代 BP1AForm 中的属性。现在就可以通过 BP1BForm 访问 BP1AForm 中的属性子集了。清单2展示了访问的方式。

  1. 清单 2. 访问 JSP 中的表单属性
  2. <html:formaction="/bp1">
  3. <bean:definename="bp1AForm"property="bp1BForm"id="bp1B"
  4. type="com.ibm.dw.webarch.struts.BP1BForm"/>
  5. <html:textname="bp1B"property="subsetAtt1"/>
  6. </html:form>

要点

这种实践的主要优势是可用于多个 ActionForm 访问一个属性集。在遵循这一最佳实践的同时,需要记住以下几点:

1.Struts 实现 <bean:define/> 标记。

2.当代码 <%@ taglib uri="struts-bean.tld" prefix="bean" %> 指向 struts-bean.tld 时,<bean:define/> 标记开始在 JSP 组件内工作。

3.由 ActionForm 扩展而来的 BP1AForm 验证框架必须验证 BP1BForm 的数据。

4.当在应用程序中创建 Action 类时,不需要直接扩展 org.apache.struts.action.Action,可以通过扩展 org.apache.struts.action.Action 创建一个 Action 类(Inter

最佳实践 2. 使用 Action 类处理请求

通常,在使用这个 Struts 框架时,对于 JSP 组件请求应用程序执行的每个动作,应用程序都必须扩展Struts的org.apache.struts.action.Action以创建Action类。在处理请求时,单个的 Action 类与应用程序的 Model 层连接。要实现这一最佳实践,Struts 建议您遵循以下步骤:

1.通过扩展 org.apache.struts.action.Action 创建一个 Action 类,比如 BP2Action。

2.通过扩展 BP2Action 在 Web 应用程序中创建所有其他 Action 类。

3.在 BP2Action 类中创建一个方法 performTask(),就像在公共抽象类 ActionForward performTask(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException 中一样。 4.在BP2Action 类中向应用程序添加一个或多个泛型方法,比如 serverSideValidate()。考虑以下因素后决定方法的访问修饰符:

◆如果所有 Action 类都必须实现此方法,则让其为抽象。 ◆如果某些 Action 类提供一个特定的实现,则将此方法声明为受保护,并给它一个默认实现。

5.在 BP2Action 类中,将方法 perform() 声明为 final。调用上述的泛型方法(通常在处理请求前调用该方法)。现在调用 步骤 3 中创建的方法 performTask()。 在每个扩展 BP2Action 的 Action 类,添加具有特定实现的方法 performTask()。

优势

这一实践有两个主要优势。首先,它避免了 Web 应用程序中每个 Action 类的冗余代码。其次,通过将 Action 类的行为集中在一起,使应用程序能够更多地控制通用的任务。

最佳实践 3. 使用 ActionForm 处理会话数据

在一个基于 Struts 的 Web 应用程序中,每个 ActionForm 都扩展 org.apache.struts.action.ActionForm 类。这些 ActionForm 封装页面数据,并提供一个验证框架来验证请求参数。

大多数 Web 应用程序都在会话中保持数据,使其在整个应用程序过程中可用。这种最佳实践实现了这种 Web 应用程序特性。它允许方法 toSession() 和 fromSession() 将会话数据移动到表单数据或从表单数据移回。因此,它实现了在 Web 应用程序中保持会话数据。要遵循一最佳实践,执行以下步骤:

通过扩展 org.apache.struts.action.ActionForm 创建一个名为 BP3Form 的抽象类。在BP3Form类中,添加具有访问修饰语的方法,就像在公共抽象类 void toSession(SessionData sessionData) 和 void fromSession(SessionData sessionData) 中一样。

在每个 ActionForm 类中,扩展 BP3Form 并实现这些抽象方法(表单数据通过它们传递到会话或从会话传回)。 相应的 Action 类可以决定这些方法的调用顺序。例如,可以在决定 actionForward 之前调用 ActionForm 上的方法 toSession()。 何时使用这一实践,这一实践最适用于:会话数据是单一对象和/或每个页操作或使用会话数据

最佳实践 4.有效处理异常

传统地,当在 Action 类中发生应用程序异常时,异常首先被写入日志。然后此类创建一个 ActionError 并在合适的作用域中存储它。然后 Action 类再将控制转交给合适的 ActionForward。清单 3 展示了 Action 类是如何处理异常的。

  1. 清单 3. Action 类中的异常处理
  2. try {
  3. //Code in Action class
  4. }
  5. catch (ApplicationException e) {
  6. //log exception
  7. ActionErrors actionErrors = new ActionErrors();
  8. ActionError actionError = new ActionError(e.getErrorCode());
  9. actionErrors.add(ActionErrors.GLOBAL_ERROR, actionError);
  10. saveErrors(request, actionErrors);
  11. }

传统的异常处理过程在每个 Action 类中保存异常信息,而最佳实践 4 则在处理异常时避免冗余代码。要使用这一最佳实践,Struts 建议您遵循以下步骤:

1.通过扩展 org.apache.struts.action.Action 创建一个 Action 类,比如 BP4Action。

2.通过扩展 BP4Action 在 Web 应用程序中创建所有其他 Action 类。

3.在 BP4Action 中声明变量 ActionErrors actionErrors = new ActionErrors();。

4.在 BP4Action 中创建方法 performTask(),就像在公共抽象类 ActionForward performTask(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, ActionErrors actionErrors) throws IOException, ServletException 中一样。

6.在BP4Action中将方法perform()声明为final。然后调用泛型方法(这些方法总是在处理请求前调用)。现在调用在前一个步骤中创建的 performTask()。

7.在每个 Action 类中实现方法performTask()的同时(通过扩展 BP4Action),像清单 4 那样处理应用程序异常。

  1. 清单 4. 有效使用 ActionErrors
  2. try {
  3. //Code in Action class
  4. }
  5. catch(ApplicationException appException) {
  6. //Log exception
  7. //Add error to actionErrors
  8. actionErrors.add(ActionErrors.GLOBAL_ERROR,
  9. new ActionError(appException.getErrorCode()));
  10. }

在BP4Action中,调用方法performTask()之后,通过saveErrors(request, errors)保存ActionErrors。

优势

这一实践主要的优势是:避免了每个处理 ActionErrors的Action类中的代码冗余。

结束语

对开发团队而言,构建易于维护的Web应用程序是一项非常具有挑战性的任务。使用Struts等成熟的框架有助于实现通常与构建应用程序相关的基础设施代码。Struts 框架提供了一组标准接口,用于将业务逻辑插入到应用程序中。此外,还提供了一种跨开发团队的一致机制,用于执行用户数据验证、屏幕导航等任务,以及用于简化开发屏幕的一组定制标记库。

本文给出的4种最佳实践对您充分利用这种框架的特性十分重要。它们不仅能够提高代码的模块化程度和应用程序的可重用性,还能减少代码冗余。对于构建可扩展的Web应用程序,这是至关重要的。

mediateAction),用于处理应用程序中的常见事务。所有其他的 Action 类都扩展 IntermediateAction 类。

 

posted on 2013-02-18 09:35  青春丶冭柔情  阅读(245)  评论(0编辑  收藏  举报

导航