[理学]基于Struts技术架构的网上书店系统的设计与实现.doc
华东师范大学学士学位论文 基于Struts技术架构的网上书店系统的设计与实现华东师范大学软件学院2006年软件工程学士学位论文基于Struts技术架构的网上书店系统的设计与实现The Design and Implementation of Online Bookstore System Based on Struts Framework姓 名: 蒋欣玮 000000 学 号: B02251423 00000 班 级: 02级4班 00000 专 业: 软件工程 00000 指导教师: 琚小明 0000000 职 称: 讲师 00000000 2006年 5月44目 录摘要IAbstractII一、背景介绍1二、Struts技术综述1(一) 为什么需要Struts1(二) Struts架构概述2(三) Struts核心组件及运行机制4(四) Struts标记库14三、网上书店系统的设计与实现15(一) 系统需求分析15(二) 系统概要设计16(三) 系统开发环境搭建18(四) 数据库设计及实现18(五) Struts相关配置文件的开发21(六) 各个模块的实现29四、网上书店应用系统测试40(一) 图书查询模块测试用例40(二) 购物车管理模块测试用例40(三) 用户注册与登陆模块测试用例41(四) 订单管理模块测试用例41五、结束语41参考文献43致 谢44 基于Struts技术架构的网上书店系统的设计与实现摘 要随着计算机技术的飞速发展,网上书店以其快速的查询和便捷的获取方式逐渐赢得了人们的目光,成为了人们接受精神食粮的最佳途径之一。作为对经典的MVC设计模式的一种具体实现,Struts是建立在当前动态网站设计领域中JSP、Servlet、XML等相关开发技术基础之上的一种主流的开发架构,在web应用系统开发中有着得天独厚的优势,开发简单,维护方便,二次开发成本节省等等。本文在做了网上书店的需求分析之后,利用Struts技术架构来设计和实现各个模块,其中每个模块都涉及了MVC设计模式的三个层次:用户表示层、控制处理层和业务逻辑层;用Oracle作为网上书店的后台数据库实现;最后使用黑盒测试来检查系统的完整性。本文通过书店这个系统,主要突出了Struts在Web应用系统以及二次开发中的优势,和它为工程管理人员所带来的管理和维护上的便利。关键词:Web应用系统;Struts技术架构;MVC模式;网上书店;JSP页面The Design and Implementation of Online Bookstore System Based on Struts Framework AbstractWith fast development of computer science, online bookstore is becoming the best way to acquire most information for people. According to the result, shopping on the Internet attracts more and more people under the high rhythm of life.As an implementation of classical design patternMVC, Struts is a popular framework based on related techniques, such as JSP, Servlet and XML. It owns excellent advantage in the developing area of Web system. Based on Struts, we could use an easy way to design, implement and maintain our system. Besides, it will save us more effort when we want to do a second-time development.In this thesis, we first analyze the requirement of online bookstore; then we design and implement every module based on Struts framework. In each module, we contain the three levels of MVC: user view layer, control layer and operation logic layer. In the system, we choose to user Oracle to implement and develop our database. At last, we use the way of “black box” to test our system. Through the design and implementation of online bookstore system, we could clearly see the advantage of Struts framework not only in the development of Web system, but also for the people to manage and maintain the system.Keywords: Web Application System; Struts Framework; MVC mode; Online Bookstore; JSP一、背景介绍Internet是目前世界上最大的计算机互联网络,它遍布全球,将世界各地各种规模的网络连接成一个整体。作为Internet上一种先进的,易于被人们所接受的信息检索手段,World Wide Web(简称WWW)发展十分迅速,成为目前世界上最大的信息资源宝库。据估计,目前Internet上已有上百万个Web站点,其内容范围跨越了教育科研、文化事业、金融、商业、新闻出版、娱乐、体育等各个领域,其用户群十分庞大,因此,建设一个好的Web站点对于一个机构的发展十分重要。近年来,随着网络用户要求的不断提高及计算机科学的迅速发展,特别是数据库技术在Internet中的广泛应用,Web站点向用户提供的服务将越来越丰富,越来越人性化。我们发现这样一个事实,在一个网站刚刚建立之初,往往所提供的功能都是非常有限的,在试运行了一段时间后,根据用户的反馈意见,很多新的功能会被添加上去。作为我们软件开发人员来说,很重视二次开发的工作量和效率。一般来说,要提高二次开发的效率,关键问题还在于一次开发时开发模型的选择。一个好的开发模型不仅在代码的管理上占有很大的优势,便于不同的开发工程师去阅读和修改代码;在二次开发时会在效率上为开发人员节省很多的精力。经过调查,发现现在网上书店在知识经济的今天在互联网上有很大的发展空间,目前所提供的功能虽然已经满足了大部分的需要,但随着用户思路的不断扩展,越来越多的新需求将被提出。本文以设计和开发一个网上书店为例,介绍了Struts架构在实现大型web应用项目中的优势。通过对网上书店的需求分析,模块设计(包括视图设计和模型设计以及数据库设计),系统测试来深入理解Struts架构,并讨论了网上书店新需求出来后,对系统二次开发的影响程度。二、Struts技术综述(一) 为什么需要Struts软件危机的产生:l 无法满足日益增长的对软件的需求l 难以满足对已有软件系统的维护软件危机的产生,使得人们去寻找产生危机的内在原因,归纳起来有这样两个原因:一方面是软件本身存在着复杂性,另一方面却是与软件开发所使用的方法和技术有关。作为现今软件开发中的一个重头戏电子商务,已日渐成为目前商务领域中非常重要的一种运作方式,如何快速、高效地构建出客户所需的电子商务网站已经成为程序员比较关心的问题。并且,随着客户对软件功能的要求越来越高,应用范围的不断扩展,在代码的移植、程序的可扩展性等方面出现了诸如重复性开发、维护困难等众多问题,Web应用系统的开发也变得越来越复杂。设计模式,作为软件危机的应对者,毫无意外地登上了IT的舞台。所谓设计模式就是对以往成功的解决方案的重复利用。对专业软件开发工程师的技术和经验的重复利用,无疑会大大降低软件开发的风险,提高软件开发的效率。MVC(Model-View-Controller,模型视图控制器)这个概念对于软件开发者来说应该都不会陌生,而Struts正是建立在当前动态网站设计领域中JSP、Servlet、XML等相关开发技术基础之上的一种主流的开发架构。Struts为Web应用提供了通用的框架,这样开发人员就可以把主要精力集中在如何解决实际业务处理问题上,但与此同时,Struts框架结构非常灵活,它允许开发人员根据实际需要进行扩展和定制,从而可以更好地适应用户的需求。总而言之,Struts的出现,很好地实现了代码的重用,使开发人员从繁琐的工作中解脱出来,并且让Web应用的开发过程大大简化,从而缩短开发周期、提高开发效率。(二) Struts架构概述1. 什么是软件开发架构(Framework)组件复用是面向对象编程思想的结晶,而在软件架构的基础上进行开发可以最大限度地实现组件的复用。通常那些被验证为有效的、相同类型问题的解决方案进行抽象,即可以提取形成一个应用程序框架,即Framework3。2. MVC设计模式MVC是Model,View,Controller的缩写,MVC是Application开发的设计模式,也就是大家所知道的Model2.在MVC的设计模式中,它包括三类对象:(1) 模型(Model)对象:是应用程序的主体部分。实现具体的业务逻辑、状态管理的功能。(2) 视图(View)对象:是应用程序中负责生成用户界面的部分。即与用户实现交互的界面,通常实现数据的输入和输出功能(3) 控制器(Control)对象:是根据用户的输入,控制用户界面数据显示及更新Model对象状态的部分。MVC应用程序总是由三个部分组成: Event(事件)导致Controller改变Model或View,或者同时改变两者。只要Controller改变了Models的数据或者属性,所有依赖的View都会自动更新。类似的,只要Controller改变了View,View会从潜在的Model中获取数据来刷新自己。MVC模式是一个复杂的架构模式,其实现也显得非常复杂,但多种设计模式结合在一起,使MVC模式的实现变得相对简单易行.Views可以看作一棵树,显然可以用Composite Pattern来实现。Views和Models之间的关系可以用Observer Pattern体现。Controller控制Views的显示,可以用Strategy Pattern实现。Model通常是一个调停者,可采用Mediator Pattern来实现。MVC设计模式的结构及各组成部分间的通信方式如图2-1所示。图2-1 MVC设计模式的结构Figure 2-1 Structure for MVC Mode3. Struts开发框架作为基于MVC设计模式的Web应用的一种典型体现,Struts架构实际上是建立在Model 2基础之上的,对Model、View和Controller都提供了现成的实现组件,其实现方式如图2-26所示。图2-2 Struts 概览Figure 2-2 Preview of Struts(1) Controller控制器部分在Struts架构中,Controller控制器部分是通过专门的Servlet来实现的,该Servlet是一个Struts API中提供的ActionServlet类型的实例,作为javax.servlet.http.HttpServlet类的派生类,ActionServlet的实例可以和普通的Servlet一样的工作, 实际使用的servlet在配置文件中由一组映射(由ActionMapping类进行描述)进行定义。其作用就是接受客户端浏览器的请求,然后选择执行相应的业务逻辑,再把响应结果传回到客户端。(2) Model模型部分MVC系统中的Model模型部分从概念上分为下面两类:系统的内部状态以及改变系统状态的动作(事务逻辑)。在Struts架构中,Model部分一般由JavaBean以及EJB组成。JavaBean主要是提供具体的业务逻辑,即“怎么做”。(3) View视图部分在Struts架构中,View视图部门还是可以采用JSP实现,此外, Struts还提供了丰富的自定义标记库。(三) Struts核心组件及运行机制1. 概述Struts架构是将Model(模型组件)、View(视图组件)、Controller(控制器组件)这些概念分别对应到不同的Web应用组件中,图2-3就是基于MVC设计模式实现Web应用的分层结构,其中表示层一般使用视图组件实现,控制层使用控制器组件实现,而业务逻辑层则使用模型组件来实现。作为表示层和业务逻辑层之间的中介,控制器处于视图及模型之间,起到了桥梁的沟通作用。在Struts架构中,每一层都提供了相应的实现组件。表示层控制层业务逻辑层层数据库图2-3 Web应用的分层模式Figure 2-3 The delamination pattern for Web application我们下面用以前在UML上学到的序列图2-4来显示整个Struts架构从接受请求到返回相应的完整的一个工作流程,其中我们可以清楚地看到所涉及的核心组件所处的位置及功能,以及各部门协调配合的工作过程。图2-4 Struts的请求响应处理流程Figure 2-4 Process of “Request-Response” in Struts在这个序列图中,我们可以大致看到整个Struts架构是如何实现对客户请求的一个相应:Ø 客户请求匹配Action URI 样式的路径 (1).Ø 容器将请求传递给ActionServlet.Ø 如果这个是模块化应用,ActionServlet 选择响应的模块。Ø ActionServlet 查询路径的映射。(来自于配置文件)Ø 如果映射标明了一个form bean,ActionServlet 看是否已经有一个实例,或者创建一个新的实例 (1.1)。如果已经有一个form bean,ActionServlet 重设它,并根据HTTP 请求重新组装它。Ø 如果 mapping 的 validate 属性设置为 true, 它将调用 form bean 的validate 方法(1.2)。Ø 如果失败,Servlet 将控制转发到input 属性标明的路径,控制流终止。Ø 如果mapping 标明一个Action 类型,如果它已经存在或已经实例化,它将被重用(1.3)。Ø Action 的perform 或 execute 方法被调用,并传递一个实例化的form bean(或者 null)。Ø Action 组装form bean, 调用业务对象,以及其他需要做的事情。 (1.3.1-1.3.4)。Ø Action 返回一个ActionForward 给ActionServlet (1.3.5).Ø 如果ActionForward 指向另一个 Action URI,重新开始; 否则,显示页面或者其他资源,流程结束。通常,结果是一个JSP 页面,或者Jasper, 或其它类似技术 (非Struts)渲染的页面。 (2,3). Ø 如果JSP 中使用了Struts HTML 标记, 并且在请求中看到正确的ActionFormØ (1.1),他们会从ActionForm 中组装HTML 控件。否则, <html:form> 标记将Ø 创建一个。从Struts 1.1 开始, 如果form 标记自行创建一个ActionForm ,它将Ø 调用ActionForm 的Reset 方法。如果你只是想创建一个空白的表单 (1.1),你可以Ø 使用标准的ForwardAction 来通过Action 传递控制,然后离开页面。下面就分别来介绍一下各个层次中的主要组件。2. 控制器组件作为模型组件和视图组件的“控制中枢”,控制器组件在整个Struts架构中所承担的主要功能如下:u 接受浏览器客户端的处理请求。u 根据用户的不同请求,调用对应的模型组件来执行相应的业务逻辑。u 获取模型组件业务逻辑处理结果。u 根据当前的状态数据以及业务逻辑的处理结果,选择合适的视图组件呈现在浏览器客户端。在Struts架构中,整个控制工作是在一系列相关组件的配合下共同完成的,下面对这些组件一一介绍。(1) ActionServletActionServlet是Struts架构中最为核心的控制器组件,它是一个org.apache.struts.ActionServlet类型的Servlet。所有的客户端请求都由它进行处理,ActionServlet负责在接收到客户端请求后将之分到相应的ActionBean处理,再根据处理的结果将不同的显示请求重定向到响应的JSP页面中进行显示。事实上,ActionServlet完全是在幕后工作,它将其他组件绑定在了一起。和其他的HttpServlet一样,ActionServlet类继承了javax.Servlet.http.HttpServlet类并实现了包括init()、doGet()/doPost()以及destroy()等HttpServlet生命周期中所要用到的所有方法。此外,org.apache.struts.ActionServlet类中还添加了一个特殊的process()方法。process()方法的作用是处理接收的请求并做出响应,该方法本身并不复杂,关键是在具体应用时往往会在该方法中调用其他相对复杂的方法,比方说,在方法中调用模型组件中所提供的包含大量业务逻辑的方法。当ActionServlet接收到来自于Servlet Container的新的客户端请求时,它所采取的具体步骤如下: 根据请求的种类执行相应的doPost()或doGet()方法,然后在doPost()/doGet()方法中调用前述的process()方法。ActionServlet的process()方法首先获取当前的RequestProcessor对象,然后调用该RequestProcessor对象的process()方法进行处理。实际上控制器所执行的控制逻辑就包含在这个RequestProcessor类、而不是ActionServlet类中,即ActionServlet的真正工作是借助RequestProcessor实现的。RequestProcessor的process()方法从配置文件struts-config.xml中根据请求URI查找匹配的<action>子元素,并且进而根据<action>子元素的“name”属性在该配置文件中查找匹配的<form-bean>子元素,确定下一步要用到的ActionForm Bean.RequestProcessor的process()方法调用ActionFormBean的setXXX()方法,将请求表单中提交的数据填充到FormBean的相应属性中去。RequestProcessor的process()方法根据步骤3)中查找到匹配<action>元素的“type”属性寻找相应的可用ActionBean对象,如果找不到的话就创建一个新的,然后将包括FormBean在内的请求相关信息分发给该ActionBean对象,并调用Action Bean的execute()方法进行处理。 Action Bean的execute()方法执行完毕后,返回一个用于表明目标相应页面的ActionForward对象,RequestProcessor的process()方法恢复其控制,将请求重新定向到制定的目标相应页面。(2) RequestProcessor实际应用中,org.apache.struts.action.RequestProcessor类中真正包含了Struts控制器在处理Servlet请求时所遵循的控制逻辑。在Struts架构中,只允许应用提供一个ActionServlet类,但是根据需要可以存在多个客户化的RequestProcessor类。ActionServlet就是通过调用RequestProcess对象的Process()方法,来处理客户端请求的。方法格式如下:public void process(javax.Servlet.http.HttpServletRequest request,javax.Servlet.http.HttpServletResponse response) throws java.io.IOException, javax.Servlet.ServletException 在RequestProcessor类中还定义了多个processXXX()方法,例如processMapping(), processForwarConfig()方法等等,process()方法正是通过这些方法来完成具体处理工作的。(3) ActionForm在Struts架构中,通常使用ActionForm的系统状态Bean来实现应用系统的非持久性数据存储和维护功能。具体来说,这种类型的对象主要用于保存用户请求表单中的数据,并可保持其状态的连续性,即在不同的页面间传递这些数据。在通常情况下,该Bean必须是Struts API中定义的抽象类org.apache.struts.action.ActionForm的子类的实例。作为抽象类的ActionForm主要用来标识这些特定的Bean在整个体系结构中的作用,因此典型情况下,在由开发者定义的子类中主要包含和用户表单数据同名的属性以及相应的存取方法,并没有商业逻辑。此外,在子类中根据需要还要重写从父类继承而来的reset()和validate()方法,实现属性重置和表单数据验证功能。 ActionForm Bean的处理过程:控制器ActionServlet收到客户端请求,将请求委托给RequestProcessor对象进行处理。按照struts配置文件struts-config.xml中与该请求匹配得<action>子元素得约定对该请求进行处理得,根据<action>元素得name属性在规定的范围内找到指定的ActionFrom Bean, 如果找不到则自动创建一个新的Bean实例。RequestProcessor随后重置该表单Bean的状态,即使用请求表单中的数据自动填充其相应属性。然后该Bean被作为参数传递给相应的处理器Action对象的execute()方法开始后续的处理过程。ActionForm Bean的一个具体的生命周期就是如下显示:(4) ActionAction类是Struts架构中控制器组件的重要组成部分,是Struts API中定义的一个重要组件类型org.apache.struts.Action,它是客户请求和业务逻辑之间沟通的媒介。每个Action类型的对象实际上都在充当客户的业务代理。打个简单的比方来说,比方说一个规模很大的软件开发企业接到了一个项目,它会根据客户对技术实现类型的需求,.NET还是Java,来把项目安排给相对应的部门来完成。 当Struts应用程序的控制器ActionServlet委托RequestProcessor对象处理接受到的一个客户端请求时,RequestProcessor对象除了使用表单Bean接受请求表单信息外,还会查找配置文件Struts-config.xml文件中的<action-mapping>元素,根据请求页面的URI确定匹配的<action>子元素,则匹配的处理器类就是定义在<action>子元素中的type 调用ActionForm对象的reset()方法取出ActionFrom对象,如果没有,则自动创建一个控制器接受请求将ActionForm对象保存在制定的范围中将用户提交的表单数据封装在ActionForm对象中若<action>的validate属性为true,则调用validate()方法Validate()出错YesNo将请求转发给<action>的input属性指定的Web组件,将ActionForm保存在制定范围内调用action的execute()方法,并将ActionForm对象传递给execute()方法将请求转发给指定的Web组件,将ActionForm保存在指定范围内图2-5 ActionForm Bean生命周期Figure 2-5 Life Circle of ActionForm Bean值,然后将该请求发送给该处理器对象,并调用处理器对象的execute()进行处理。execute()方法时org.apache.struts.action.Action类中定义的一个重要方法。在设计Action Bean的过程中,通常我们需要注意一下几点:1) RequestProcessor对象对于每种Action Bean类型只创建一个实例,该实例将被用于所有匹配的请求。为了保证能使之在一个多线程环境中正常运行,在Action Bean类中尽量只使用局部变量而不是实例变量。局部变量的作用域被限定在所在的方法体中,其生存期只限于所在方法的一次运行期间,不存在被多个请求处理线程共享的问题。2) 尽量在Action Bean类中加入异常处理逻辑,在方法内部捕获和处理可能抛出的异常,而不是简单地将其抛出3) 避免设计出非常大的Action Bean类。虽然实现起来最简单,但这会导致使Action Bean类的可读性和维护性变差,重用性也会大大地降低。(5) ActionMappingActionMapping是Struts API中定义的又一个重要的核心组件类型org.apache.struts.action.ActionMapping类, 一个ActionMapping对象描述了Struts框架结构是如何处理每一个离散的业务操作的(Action)。在Struts中,每一个ActionMapping都是通过path属性来和一个指定的URI相关联。当HTTP请求到来时,ActionServlet通过path属性来选择对应的ActionMapping对象。全部的ActionMapping对象都是存放在一个ActionMapping集合中。ActionMapping对象一般是通过Struts配置文件来创建的。ActionServlet都是通过ActionMapping来决定下一步如何进行:它需要将控制转移到另外一个资源上;或者它需要填充或者校验一个ActionForm对象。在某些时候,它也许还需要将控制转交给一个Action对象,并且当Action对象将控制返回时,还要查找与ActionMapping相关的ActionFord对象。打个比方来说,ActionMapping就象servlet的一个路由表,根据这张表,请求可以被传递到任何一个地方。ActionMapping对象映射的配置信息主要来自于配置文件中的<action-mappings>和<global-forwards>元素,ActionMapping的一些属性:path属性指向ActionMapping的虚拟引用forward属性当指定forward属性时,servlet不会将请求传递给一个Action对象,而是会调用Request Dispatcher.forward方法。include属性当指定forward属性时,servlet不会将请求传递给一个Action对象,而是会调用Request Dispatcher.include方法。type属性在大多数的应用中,ActionMapping对象会指定一个Action类而不是forward或者include。一个Action类可以被一个或者多个ActionMapping对象使用。(注意:在定义ActionMapping的属性时,forward, include, type属性值是彼此互斥使用的)classname属性若指定该属性,则该属性值指定的Java类名应该时ActionMapping的子类的类名。name属性该属性指定form bean的逻辑名。roles属性该属性指定了一系列角色名。具有这些角色的用户才被允许访问该Action-Mapping对象。validate属性当ActionMapping的validate属性设置为真时,ActionServlet会调用ActionForm的valdite()方法。input属性当ActionForm的validate()方法返回假时,该属性值定义了向何处传递控制。(6) ActionForwardActionForward对象时一种配置对象,代表了web资源,可以是JSP页面、Servlet以及Action。ActionForward对象映射的是配置文件struts-config.xml中的<forward>元素,封装了目标响应页面的URI.ActionForward类的主要属性有:name作为ActionForward对象的标识,在Action Bean类的execute()方法中,ActionMapping对象的findForward()方法就是根据此标识来查找相应的ActionForward对象的path目标响应页面URIredirect标明页面转向的方式ActionForward对象被返回给RequestProcessor后,后者将调用相应的RequestDispathcher.forward()或response.sendRedirect()方法转向下一个响应页面。具体使用forward()还是sendRedirect()方法取决于ActionForward对象的属性redirect的值。此属性值来自于配置文件中的<forward>元素。此外,<forward>元素不但可以定义在<global-forwards>元素中,作为全局性配置信息,还可以定义在<action>元素中,此时只用于特定的Action处理过程。3. 模型组件(JavaBean)事实上,在Struts架构中没有为设计和创建模型组件提供现成的框架。我们通常就是在Struts中使用其他模型框架来处理应用业务逻辑,包括JavaBean、EJB及ORM等。基于模型的软件设计可以带来许多的优势,例如组件可重复使用、易于替换和升级以及能够加速软件开发速度等等。 Java开发人员一般使用JavaBean来实现Model组件,对应着可以分为两方面,记录系统状态和封装业务逻辑,即包含了业务实体和业务逻辑的Bean。(1) Bean的概念和使用范围首先,Bean是一个Java对象,用于封装信息或业务逻辑。在Web应用中,使用一些定制标记,可以方便地实现Bean对象的自动创建和属性存取操作。除此之外,能够在规定的范围内实现Bean的共享使用,起到简化编程等作用。Bean的使用范围是指一个Bean的定义生存期、即在多大范围内可用,是一个非常重要的概念。JSP规范规定了下述4种Bean的使用范围。1) page范围Bean对象只在一个单独的JSP页面中可见,其生存期仅限于当前请求。2) request范围同一个Bean对象不仅在当前JSP页面有效,还可包含在该页面或从该页面提交到的其他页面被访问到。3) session范围同一个Bean对象在属于同一个用户会话过程Session的所有JSP和Servlet页面中都是可见的,即可以跨越一个或多个请求而保持其状态(属性值)的连续。4) application范围同一个Bean对象在整个web应用程序的所有JSP页面和Servlet中都是可见的。(2) 系统状态Bean和业务逻辑Bean1) 系统状态Bean(Application Bean)顾名思义,系统状态Bean主要用于封装和维护系统状态信息,一般通过定义相应属性来实现。在我们的web应用中,网上商店经常使用的购物车Bean就是一种典型的系统状态Bean,该Bean的作用是维护单个顾客的购物情况信息,通常包括顾客当前已选购的商品项目信息、顾客的个人信息等等。当然系统状态信息不仅限于此,还可包括请求表单中的数据,永久性保存与外部数据库中的数据。在大型的应用中,通常使用一种企业级的JavaBean(Entity EJB)。2) 业务逻辑Bean(Business Logic Bean)相对于系统状态Bean侧重于信息的维护和记录、包括存取这些简单操作来说,业务逻辑Bean主要用于封装具体的商业逻辑,即处理信息的规则,一般通过定义相应的方法来实现。在实现方式上,既可以将这些封装了具体商业逻辑的方法定义在单独的Bean类中,再将系统状态Bean作为参数传递给这些方法进行处理;也可以将之直接定义在系统状态Bean类中,但是这样做的话,会使代码的重用性大大降低。4. 视图组件视图组件主要是为浏览器客户端提供动态页面的显示而服务的,是模型的外在表现形式,同一个模型可以对应着多个不同的视图。在Struts架构中,View组件主要表现为JSP页面和用户标记库。视图组件提交请求的方式主要有HTML表单和HTML超链接等。用户可以通过HTML表单中的Action属性来发出请求,并同时将相关数据提交给对应的Acti