在本系列的的第一篇中,我们大致浏览了Struts框架,框架的功能以及框架中应用到的各个模块。而本文,我将利用Struts 1.0为大家演示建立一个简单的应用;在第三篇文章中将介绍如何利用Struts的标签在JSP中访问ApplicationResource文件中的信息。
我们在这篇文章将会一步一步的讲解Struts的应用,以这样的形式打开Struts一道道神秘的大门,通过这样的过程,相信也能激起你在应用开发中如何应用Struts的灵感。如果你对Struts的一些术语不是很清楚的话,可以参考本系列前一篇对Struts作大体介绍的文章。
再次重复一遍,本文需要读者有如下几方面的知识和经验:JSP,Servlets,自定义标签库(Custom Tag libraries)和XML。此外,在本文中,我还会用到Jakarta项目组其他一些好东东,比如Tomcathttp://jakarta.apache.org/tomcat/index.html(实现Java Servlet和JSP官方标准的Servlet容器,通俗的讲就是一个JSP的Web Server啦)和Anthttp://jakarta.apache.org/ant/index.html(基于Java的自动编译发布工具,这可是好东东啊)。
作为一名一直使用前沿技术开发了诸多应用的技术人员,我一直坚信掌握新技术,理解该技术开发的逻辑是至关重要的。但这往往就是陷住我们学习步伐的泥潭,正因如此,我打算将利用Struts开发的一套完整流程作为我们教学的案例。该流程的这个案例可谓“麻雀虽小、五脏据全”,你完全可以将这个流程应用到你手头那些复杂庞大的项目中,至少在我们的大项目中应用这个流程效果不错。
有开发复杂商业应用的开发人员都知道,客户的需求总是在不停变幻,所以如果有一套规范的开发流程来遵循,当客户提出新的需求时,我们至少可以明确哪些“无理”需求其实是合理可行的。好,接下里我将在我的这个例子中向各位展示和应用整个流程。
本文中的示例代码是StrutsSample应用中的一部分,包括build.xml的完整代码可以到此处http://www.onjava.com/onjava/2001/10/31/examples/StrutsPartII.jar下载。
Struts开发过程 从Struts发布的版本号可以看出,Struts是个新玩意,她有好几个部分组成,明智的你如果搞清楚了何时该开发完成合适的部分,那将会更好的利用我们的开发时间。从我所开发的几个利用Struts应用中,我大致总结出如下这个比较有效的开发步骤:
1,明确应用需求;
2,由用户输入和获取数据的角度出发,明确和设计出每一个用户界面;
3,确定用户界面的进入路径;
4,由应用逻辑信息确定动作映射表(ActionMapping);
5,由设计完成的用户界面开发其所用到的类和应用函数;
6,由用户界面中的数据信息开发ActionForm和相应的数据校验方法;
7,ActionMapping中将会被调用相应的Action或转到相应的JSP页面,这一步我们先开发这些Action;
8,开发商业应用逻辑,就是相应的JavaBean、EJB或其他东东;
9,开发由ActionMapping定义的系统工作流程完成对应的JSP页面;
10,完成系统配置文件:struts-config.xml和web.xml;
11,编译/测试/发布。
明确应用需求 开发任何应用系统的第一步就是收集用户需求信息。不管一个用户逻辑初看上去多么合理,但总有可能在开发时才发现它比看上去要难得多。所以,建议拟一份明确的用户需求列表,这不只是出于开发的目的,还能通过该表分析用户需求以确定哪些地方可能需要花更多的精力。
在我们这个StrutsSample项目中,应用需求就是:
作为一个展示Struts框架应用的完整例子,本示例完成的功能是用户登录。目的只为明确Struts的应用,本示例将不会涉及到一般复杂应用系统中可能应用的安全、数据库、EJB开发等等相关技术。
设计用户界面 这个应用中,包括如下三个用户界面:
1)登录界面,用于用户名和密码输入;
2)当登录用户为合法用户时的欢迎界面;
3)当登录失败时的错误提示界面。
确定用户界面的进入路径 1)登录界面作为这个应用的默认页面;
2)欢迎界面只有当成功登录后才能进入;
3)任何可能发生错误的页面能可以进入错误提示界面;
由应用逻辑信息确定ActionMapping ActionMapping为整个应用确定的“线路图”,在配置文件struts-config.xml对ActionMapping进行定义,通过转发请求(forward)来理顺应用的处理流程,确定应用中每个用户请求对应的动作。
通常我们在开发过程中就逐步确定了ActionMapping所需的信息,开发代码的过程就是在由草稿开始一步步完善struts-config.xml的过程。当Action类处理完用户请求后,其返回的的forward就是在ActionMapping中定义的一个。一个Action返回的forward完全有多种可能,尽管一个Action一般只定义其相关的几个forward。那么,如果有多个Action都可能返回的同一个forward,那么就可以将其定义为全局转发(global forward)。这类似于C中的头文件中全局变量,如果在struts-config.xml描述信息中,某一个forward并不是在当前Action描述中定义的而是全局定义的,那么这个全局的将起作用,同样,一个Action中当前定义的forward将覆盖全局定义。在我们所给的这个简单实例中,我们定义了全局forward??“error”,当某Action返回的forward是“error”这个映射,那么Errorpage.jsp页面将会显示给用户,尽管当前Action并没有对其定义。
我们继续不断的开发,项目日渐完善,项目相关的配置文件也会越来越详细。在下面的例子中,我们将以StrutsSample中用到的struts-confug.xml文件为例,学习global forward和一个Action中相关映射的定义。下面定义了一个名为“login”的Action,其为com.oreilly.actions.LoginAction的实例,当Action处理用户登录成功后将一个名为"success"的forward返回,用户也就会看到Welcome.jsp页面,如果登录失败,Action将返回对应的forward以再显示Login.jsp给用户,而如果处理过程中发生其他错误,Action将返回全局定义的forward??“error”,用户也就会看到错误提示页面Errorpage.jsp。
type="com.oreilly.actions.LoginAction"
name="loginForm"
scope="request"
input="/Login.jsp">
在前一篇文章中,我们曾说过,struts-config.xml就是MVC模式的的Controller。在确定struts-config.xml中的配置信息时,应该多花些时间精力在上面,以保证每一个Action定义及其相关定义是符合应用的需求的。如果在项目开始没有详细的设计其定义,当将所有代码和配置集成到一起的时候,我们将不可避免的将各部分的代码和配置完全重新组织一遍。
我们当前的例子StrusSample因为只是处理用户登录,所以只需要一个Action。一个应用系统中所要用到的Action的多少完全依应用的大小而定。一旦整套Action的映射完全的定义出来后,我们就可以一个一个开发其具体实现的Action和ActionForm类,并逐渐将完成的部分一点一点集成起来。
由设计完成的用户界面开发其所用到的类和应用函数 所有ActionForm的实现类都是org.apache.struts.ActionForm的子类。一个ActionForm是与页面上的输入表单相关联的,而且ActionForm的实现还可以对用户输入数据的合法性进行验证。作为一个Java Bean,ActionForm有Set和Get方法,当一个页面中表单被提交时,系统将自动调用Set方法将数据放入ActionForm中,而Get方法将为在Action中操作这些数据所提供。一般来说,处理表单中的所有数据,并进行合法性验证都完全可以交由ActionForm来完成。在应用中,就我个人而言,倾向于将ActionForm和Action划分到不同的包中,因为当一个页面中要用到几对ActionFrom和Action时,都放在一个包内会混淆的。下面的代码,就是实例中登录页面用到的ActionForm的代码。
<
查看本文来源
Web应用开发早期曾经是那么的“简单”,那个时候还只是纯HTML页面和浏览器特效而已。由于还涉及不到动态数据操作和商业应用,也就省去了很多麻烦。但是这样的“简单”只是过眼云烟,如今我们不得不为复杂的基于Web的商业应用开发采用诸多技术。
本文将介绍如何利用Struts进行应用开发的前台整合的开发过程。Struts是一个为开发基于模型(Model)-视图(View)-控制器(Controller)(MVC)模式的应用架构的开源框架(译注1),是利用Java Servlet和JSP构建Web应用的一项非常有用的技术。
阅读本文需要读者具有以下几方面的开发经验:JSP、Servlet、自定义标签库(custom tag library)和XML。如果读者想补一补自定义标签库的知识,可以参考作者以前关于这方面的文章。而本文也是关于介绍如何使用Struts系列文章的上半部分,本系列暂定分为上下两部分。
新手上路注意事项 Struts是一个基于Sun J2EE平台的MVC框架,主要是采用Servlet和JSP技术来实现的。其最初萌芽于Craig McClanahan的构思,诞生至今也一年有余了(译注2)。现在,Struts是Apache软件基金会旗下Jakarta项目组的一部分,其官方网站是http://jakarta.apache.org/struts。由于Struts能充分满足应用开发的需求,简单易用,敏捷迅速,在过去的一年中颇受关注。Struts把Servlet、JSP、自定义标签和信息资源(message resources)整合到一个统一的框架中,开发人员利用其进行开发时不用再自己编码实现全套MVC模式,极大的节省了时间,所以说Struts是一个非常不错的应用框架。
目前的Struts 1.0修正版包括完整的文档,既可以说是用户文档又是开发指导文档。如果读者是JSP新手,或者对MVC设计模式不是太熟的话,可能刚上路时会比较慢,不过不用担心,要相信自己会尽快赶上的:)
此外,应该注意到尽管当前Struts只是1.0版,但已经相当稳定了,作者从Struts 0.9版就在一个大规模的项目中应用了(最近升级到1.0版),至今还没有遇到什么麻烦问题。实际上,Struts在这个要开发复杂用户界面的项目中,为我们团队大大的缩短了开发时间,在此衷心的感谢Struts项目团队的所有开发人员。
哦,还有,如果读者开始上路了,要知道Struts的邮件列表可是有相当分量的,在这里混混才可保证能及时跟上Jakarta项目的最新动态哦 http://jakarta.apache.org/site/mail.html。
开始上路! Struts框架可分为以下四个主要部分,其中三个就和MVC模式紧密相关:
1、模型(Model),本质上来说在Struts中Model是一个Action类(这个会在后面详细讨论),开发者通过其实现商业逻辑,同时用户请求通过控制器(Controller)向Action的转发过程是基于由struts-config.xml文件描述的配置信息的。
2、视图(View),View是由与控制器Servlet配合工作的一整套JSP定制标签库构成,利用她们我们可以快速建立应用系统的界面。
3、控制器(Controller),本质上是一个Servlet,将客户端请求转发到相应的Action类。
4、一堆用来做XML文件解析的工具包,Struts是用XML来描述如何自动产生一些JavaBean的属性的,此外Struts还利用XML来描述在国际化应用中的用户提示信息的(这样一来就实现了应用系统的多语言支持)。
好,下一步咱们来看看构成这个框架的各个部分以及相互之间是怎样运作的吧!
搞定配置先 在使用Struts之前,咱们必先设置好JSP服务器,以便让服务器在用户请求时,知道该如何将指定后缀的请求转到相应的Controller-Struts ActionServlet处理,当然,这些配置信息都一般在服务器启动时通过web.xml文件读入的。我们可以在web.xml定义多个Controlloer,为每一个应用定义一个。一个典型的web.xml文件配置如下,其中有相应的注释,很好懂的,在后面讨论Action的时候,我们将主要分析strutc-config.xml。
<web-app>
<servlet>
<!--
以下配置信息声明了Struts中的ActionServlet,即一个名为OreillyAction的Servlet,其具体实现为org.apache.struts.action.ActionServlet。在这个配置中还有这个Servlet的两个参数:debug level和detail,此处这两个参数的值都设为了2,此外还设置了在启动载入时创建两个实例。
-->
<servlet-name>OreillyActionServlet</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!--
设置所有后缀为.action的请求,都转发到OreillyActionServlet
-->
<servlet-mapping>
<servlet-name> OreillyActionServlet </servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<!--
将初始请求页面设置为login.jsp
-->
<welcome-file-list><welcome-file>login.jsp</welcome-file></welcome-file-list>
<!--
设置Struts的JSP页面要用到的标签库和她们的路径
-->
<taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
</web-app>
控制器(Controller) Controller是这个框架中扮演“交通警察”的角色,当客户端与服务器有交互动作时,都由她来控制。Controller将HTTP请求封包并转发到框架中相应的对象,这些对象可能是一个JSP页面或一个Action。
Controller在web.xml中设置为org.apache.struts.action.ActionServlet的一个实例,在本例中,这个实例就是OreillyActionServlet。在一个完整的控制过程中,也就是处理一个HTTP请求时,在控制过程之初,这个Servlet会从一个配置文件struts-config.xml中获取请求与控制动作向对应的配置信息,这个我们会在后面详细讨论,Controller通过这些配置信息来决定HTTP请求该往何处转发,而这些Action在接收到转发来的请求后,实现真正的商业逻辑。我们要注意的非常重要的一点是Action对象要能够调用这个ActionServlet的若干方法,通过这个有力的特性,当Action对象在控制过程中将请求再向别的Action对象转发时(最初的请求是由ActionServlet获取,向Action对象转发,而Action对象还可以再转发到别的对象),我们可以将一些需要共享的数据对象通过调用一些方法放入这个Servlet相关的一些标准容器中捎带过去。
模型(Model) 所谓Model就是在对用户请求的整个控制过程中,真正处理用户请求并保存处理结果的对象,在整个过程中,我们一般利用JavaBean来把一些信息保存起来以便在各个对象之间传递。因为在框架中,Model对象是真正处理商业逻辑功能的对象,因此也就是框架中应用需求实现相关性最大的部分。在Struts的实现里,Model的具体表现形式就是ActionForm对象和与其对应的Action对象了。对用户提交表单的数据进行校验,甚至对数据进行预处理都能在ActionForm中完成。通常的应用中,一般是一个Model对象和一个请求页面对应的关系,但也可以一个Model对象对应多个页面请求。如果struts-config.xml配置文件没有指定一个Model对象对应的Action,那么控制器将直接把(通过Model对象完成数据封装的)请求转到一个View对象。
struts-config.xml 前面多次提到的struts-config.xml配置文件是整个框架的主心骨。web.xml文件定义了一个请求到来应向何处转发后,后面的工作就全权由struts-config.xml管理控制了。可以说struts-config.xml就是整个Struts框架的“扛把子”(译注3),只有这位“老大”清楚所有请求与动作的映射关系,要是他哪里没有搞定或不爽的话,整个“社团”就什么也摆不平了:)如今的应用系统,XML形式的配置文件越来越多,如果整个系统只使用一个这样的配置文件的话,那么保持整个系统的模块化和可维护性都非常的轻松。使用配置文件来描述请求-动作的控制过程和相互关系,而不是在代码中将对象之间的调用关系写死,那么都应用系统有变动时,我们只用修改配置文件就行了,而不是再重新编译发布程序了。
Controller通过struts-config.xml文件的配置信息确定当有请求时应该调用那个对象来处理,从效率的角度出发,这些信息都是在系统启动时读入并存在内存中的。下面我们将讲解一个极短小的struts-config.xml文件,文件中定义了一个与登录请求对应的登录动作,请求到达后将被转发到com.oreilly.ui.authentication.actions.LoginAction这个Action对象,该对象处理
查看本文来源