ZhangLiHai.Com Blog


用Struts Framework开发应用程序(二)

张利海 于 2003年05月06日 发表

用Struts Framework开发应用程序

作者: BUILDER.COM
Thursday, May 23 2002 2:15 PM


Struts Framework是一种基于Java的技术,Web应用程序开发人员通过Struts Framework即可充分利用面向对象设计、代码重用以及“编写一次、到处运行”的优点。Struts提供了一种创建Web应用程序的框架,其中对应用程序的显示、表示和数据的后端代码进行了抽象。

Struts最早于2002年5月作为Jakarta项目的组成部分问世,Jakata项目由Apache Foundation.运做。项目的创立者希望改进和提高Java Server Pages (JSPs)、servlet、标签库以及面向对象的技术水准。在钻研Struts之前你应该比较熟悉JSP、Java编程和一定的设计模式,尤其应该了解MVC(Model-View-Controller:模型、视图和控制器)软件程序架构。学习Struts一开始会比较难,一旦理解了这一技术你将发现自己掌握了一种开发大规模Web应用程序的设计利器。

MVC原理


Struts是对MVC设计模式的一种实现。MVC设计模式为构建可扩展、可重用的代码打下了一个坚实的基础。MVC设计模式最吸引人之处在于它迫使你必须抽象自己的代码,把项目分解为表示、逻辑和控制三部分,它们的作用正如一个交响乐团中的音乐、团员和指挥。

MVC设计模式中的“模型”指的是真正完成任务的代码。对大多Web应用程序来说,功能比界面感觉更重要。在模型同界面相分离的情况下,代码即可实现可管理性和可重用性。比方说,假如你开发了一个保险应用程序,其中的“模型”就是处理要求、计算保险费和同数据库交互的那些代码。模型通常也被称做“业务逻辑”。

所谓的“视图”其实就是界面。在MVC模式下,通常的设计前提是界面任务并不大。当然,视图应该具有一定的功能性并遵守可用性的约束,但视图(界面)不应当处理数据。事实上,界面的每一部分都只能包含采集数据的足够逻辑并把它传递给设计模式中的其他组成部分供处理。从理论上说,如果你在模型中实现全部业务逻辑那么你可以创建多个视图,也就是桌面应用程序、数据库系统或者Web应用程序的界面。由于所有最麻烦的工作代码都保存在了模型上,所以创建新的视图并不令人感到过分的痛苦,产生软件编码错误的可能性也就随之大大降低了。

“控制器”控制着模型和视图之间的交互过程。它决定着向用户返回怎样的视图、检查通过界面输入的信息以及选择处理输入信息的模型。

在介绍了MVC之后,现在我们就下载Struts Framework、了解Struts采用MVC设计技术的原理。

获取Struts Framework
Struts Framework 可以从Jakarta项目的网站上获取。目前可用的代码版本还是1.0,但该版本是稳定和成熟的版本。同Apache Foundation维护的其他项目一样,Struts Framework是一种开放源代码软件,所以你可以获得软件源代码亲自编译程序或者直接下载二进制版本。大多数用户并不需要源代码,但知道它的存在也不是坏事,说不定以后就用得着。

Struts分派版随带了众多示例,所有这些示例都打包为WAR文件(Web Application Archive)供部署在应用服务器上。假如你想用Struts创建自己的应用程序,那么你会在Struts库目录下找到所有你需要的东西。在这个目录下有个JAR文件包含了所有的框架源代码和标签库的全部定义。在创建新应用程序的时候需要把这些文件拷到WEB-INF目录下供部署用。将来我们会撰文讨论如何完成这些工作,目前你仅需要知道它们都放在什么地方就可以了。

MVC和Struts Framework
现在我们就看看Struts Framework是如何采用MVC模式来创建Web应用程序的。

视图

Struts采用JSP作为MVC的视图。每一视图都是采用了定制标签库的JSP页面,这些定制标签库则由Struts Framework提供。全部表单元素都是用定制标签编码的,所以这些页面能够很方便地同控制器交互。每一个表单都通过映射JSP到servlet的请求这一方式指向控制器的特定入口点。

控制器

控制器就是Java servlet,由Struts Framework提供,负责视图和模型之间的交互。控制器的每个入口点都由名为struts-config.xml的配置文件设置。该文件把来自视图的请求映射为特定的java类以进行相应的处理。控制器还指定下一个视图的位置。

模型

Java beans就是模型的代表。对进入控制器的每个入口点来说,bean的作用是存储从视图获取的信息,同时被称为“行动类”一种Java类则被指定为对表单输入采取行动。行动类(action class)实现了业务逻辑。

以上介绍了Struts Framework同MVC之间的关系,接下来的第二部分则引领读者用Struts创建应用程序。

本文的上一部分讨论了Struts Framework同MVC设计模式之间的关系。现在你应该比较清楚Struts是如何同MVC模式各个组成部分打交道的。接下来我们继续讨论用Struts具体创建新应用程序的问题。

为了用Struts Framework创建新的应用程序,你首先得创建一个新目录树,如下所示:
MyWebApp/
WEB-INF/
classes/
lib/
然后把struts.jar文件从Struts下载目录下的lib目录拷贝到以上目录树的lib目录,同时请把所有的标签库描述符(TLD)文件从Struts lib目录拷贝到WEB-INF目录。
在本文的示例应用程序中,你将创建一个Web应用程序,它通过XML-RPC同Blogger网站管理的服务通讯。该应用程序相当简单,它由一个登录页面和提交新数据到相应服务的页面组成。登录页面会获取用户名和口令,然后把这些信息将保存在一个Java bean内。
创建web.xml文件
如清单A所示,首先得创建web.xml部署文件,它应该保存在WEB-INF目录下。该文件说明新创建的Web应用程序同时还负责实例化你的控制器servlet。

如清单B所示,servlet的定义实例化ActionServlet,它就是Struts控制器。

装载servlet之后就需要把请求映射到该servlet,如清单C所示。在本例中,所有的请求都映射为*.action的形式被传递给Struts控制器。

在清单D中指定了要装载的默认页面和用到的标签库。

在如上所示定义了Web应用程序之后我们再了解下控制器的配置细节。
控制器的配置:struts-config.xml
控制器的配置决定了发给控制器的请求将得到怎样的处理。你不妨阅读下struts-config.xml文件(如清单E、F和G所示),从中可以看出,所有冠以*.action的请求都被映射到了控制器。现在你就必须指定对每一请求该如何处理。

就我们的示例应用程序来说,你需要处理登录请求和页面提交的信息。每个视图都分别具有相应的表单Java bean和用于处理的action类。

配置文件分为两个部分:其一是表单Java bean,负责指定存储来自视图的参数值以及action映射值的Java类。第一部分(如清单F所示)处理提交的信息,而第二部分(清单G)则负责处理登录。以后我们主要讨论对表单的处理。

action映射把入站的servlet请求同表单和action类联系了起来。第1步是为登录过程创建映射。发给服务器的实际请求是页面bloggerLogin.action,但是你只设置了前半部分。接下来,你还得把所有给bloggerLogin.action的请求都保存在bloggerLogin表单Java bean内(早就配置为xmlrpc.bloggerUserForm)。xmlrpc.bloggerUserAction类负责处理这个Java bean。在action标签内的转发XML元素代表了控制器返回的视图名。每种action类都必须返回下一视图的名字,这样你就可以把文件名保存在配置文件里了。

控制器就配置好了,下面我们来看看登录视图。

创建视图

视图用JSP创建,用Struts标签库同表单Java bean交互,意味着所有的表单元素都必须用Struts标签库来创建。清单H所示为有关的源代码,你可以从中了解视图的外观。

正如你所看到的那样,除了格式化以外该文件中几乎再无其他内容。事实上,文档内连修饰性文本都没有,这是因为你已经把所有的文本保存在了一个属性文件里。在你配置servlet的时候你就会用到一个应用程序资源文件:ApplicationResources,该文件会从WEB-INF/classes/ApplicationResources.properties装载。该文件就是包含页面文本消息的属性文件。装载ApplicationResources.properties有助于创建应用程序的国际化版本。请查看清单I中显示的属性文件内容。

接下来我们再回到登录视图。如果你查看视图的HTML代码,你会注意到所有的HTML标签都是用标签库编码的。这就是Struts调整HTML文档和表单Java bean之间参数值的方法。在处理每一JSP页面时。标签库会被扩展为HTML,而内部的Java bean则包含默认值。最后出现的页面如图A所示。
图A

JSP登录页面

然后我们再看看如何创建表单Java bean以捕获来自浏览器的输入信息。
创建表单Java bean

每一个表单Java bean都是一个小小的Java类,其中包含了带设置和提取函数的属性。对视图中所具有的表单输入而言,表单视图中都具有相应的属性。如果你回忆下struts-config.xml文件中的代码,你应该记得发给bloggerLogin.action的请求都被发送给了bloggerUserForm,后者就是一个Java bean。清单J即是bloggerUserForm的代码。现在我们就来了解一下提取(getter)和设置(setter)函数如何用于操作属性。

实际上,登录视图中用到的两种属性都在Java 类中得到了表示。

为了搞清楚所有以上一切是如何组织起来的,我们再来看看action类以及业务逻辑的实现原理。
创建action类

action类的任务最繁重。Action类bloggerUserAction读取bloggerUserForm的值并将其保存到名为bloggerUser的Java bean。为什么要把这些参数值保存在Java bean里呢?这是因为今后还需要以不同形式用到这些值。实际上,它们就是会话过程中的全局参数值。这些信息之后由用户用在请求和视图之间的通讯过程中。你的action类将利用Blogger服务认证用户并且获取将要修改的有效页面。该类的代码如清单K所示。

每一种action类都必须执行一定的方法,这些方法在需要实现某些行为的时候由控制器servlet执行。如清单L所示。所用到的表单Java bean保存在ActionForm中。

你可以调用表单的参数提取方法从表单获取参数值进行处理。通过在请求中设置属性的方式,你还可以在JSP的表单中设置默认值(参看清单M)。

在清单N中,你还可以由此检查全局Java bean,也就是bloggerUser是否已经装载。否则,你可以实例化一个新的。然后给bloggerUser Java bean设置来自表单的参数值。

现在考察业务逻辑。在清单O中你提出自己的XML-RPC请求并把结果保存在 Java bean内。

在清单P,中,你把全局Java bean bloggerUser保存在b_user会话属性中,并把该用户信息转发给JSP页面bloggerPost,后者对应struts-config.xml文件中的bloggerPort.jsp。

然后,从以上代码你就可以了解到MVC模式下一系列的处理过程了,我们看看下一个视图,了解下如果从视图内同全局Java bean交互。
更智能的视图

视图并不完全排斥逻辑。有时你需要给表单自身增加点“智力”,比如动态创建表单元素或者显示对某些字段的访问等。清单Q所示bloggerPost.jsp中的表单在用户成功登录之后返回给用户,它根据先前的XML-RPC请求来动态地创建选择框。

按照清单R中的代码所示,你已经捕获了用户输入的用户名和口令值并将其链接到Java bean b_user。这正是在执行action 类的时候在会话属性的bloggerUser Java bean中保存的名字。

你还能通过b_user这个 Java bean的使用反复迭带授权可编辑的页面。b_user Java bean具有一个blogs属性,它是一个ID号的ArrayList (Struts执行b_user的getBlogs()函数获得这个属性)。ArrayList的各个元素都保存在本地Java bean b_result中,你可以用来作为html:option的值以创建弹出式菜单,如清单S所示。

最后显示的页面如图B所示。
图B

显示页面

以上的这个JSP页面不仅仅只是传递信息;它实际上还具有某些构造页面的逻辑。你也可以编写其他JSP标签来创建简单或复杂的视图。但是,这里的思想是,任何对视图的处理只能同表示视图有关。而真正的后台处理或者其他业务逻辑都不能放在JSP视图之内。

你已经看到,Struts是一种采用MVC模式创建Web应用程序的强大框架。随着你开发的应用程序变得越发复杂,你最终会发现利用这个好东西照样可以快速创建出崭新的视图、可重用的组件和Java bean。
责任编辑:炒饭

新版本Blog中有更多内容
Copyright (C)2002-2007 All Rights Reserved Powered By:ZhangLiHai.Com