第7章 Struts 与MVC 设计模式.docx

上传人:b****6 文档编号:8498103 上传时间:2023-01-31 格式:DOCX 页数:87 大小:688.02KB
下载 相关 举报
第7章 Struts 与MVC 设计模式.docx_第1页
第1页 / 共87页
第7章 Struts 与MVC 设计模式.docx_第2页
第2页 / 共87页
第7章 Struts 与MVC 设计模式.docx_第3页
第3页 / 共87页
第7章 Struts 与MVC 设计模式.docx_第4页
第4页 / 共87页
第7章 Struts 与MVC 设计模式.docx_第5页
第5页 / 共87页
点击查看更多>>
下载资源
资源描述

第7章 Struts 与MVC 设计模式.docx

《第7章 Struts 与MVC 设计模式.docx》由会员分享,可在线阅读,更多相关《第7章 Struts 与MVC 设计模式.docx(87页珍藏版)》请在冰豆网上搜索。

第7章 Struts 与MVC 设计模式.docx

第7章Struts与MVC设计模式

第7章Struts与MVC设计模式

7.1.Struts与JavaWeb应用

JavaWeb应用的核心技术是JavaServerPage和Servlet。

此外,开发一个完成的JavaWeb应用还设计以下概念和技术:

●JavaBean组件

●EJB组件

●自定义JSP标签

●XML

●Web服务器和应用服务器

图7-1:

JavaWeb应用的结构

7.1.1.Web组件的三种关联

Web应用程序如此强大的原因之一是他们能彼此链接和聚合信息资源。

Web组件之间存在三种关联关系:

●请求转发

●URL重定向

●包含

存在以上关联关系的Web组件可以是JSP或Servlet,对于Struts应用,则还包含Action。

这些Web组件都可以访问HttpServletRequest和HttpServletResponse对象,具有处理请求、生成响应结果的功能。

7.1.1.1.请求转发

请求转发允许把请求转发给同一应用程序中的其他Web组件。

这种技术通常用于Web应用控制层的Servlet流程控制器,它检查Http请求数据,并讲请求转发到合适的目标组件,目标组件执行具体请求处理操作,并生成响应结果。

下图显示了一个Servlet把请求转发给另一个JSP组件的过程。

图7-2:

请求转发

Sevlet类使用javax.servlet.RequestDispatcher.forward()方法来转发它所收到的HTTP请求。

转发目标组件将处理该请求并生成响应结果,或者将请求继续转发到另一个组件。

最初请求的ServletRequest和ServletResponse对象被传递给转发目标组件,这使得目标组件可以访问整个请求上下文。

值得注意的是,只能把请求转发给同一Web应用中的组件,而不能转发给其他Web应用组件。

如果当前的Servlet组件要把请求转发给一个JSP组件,如hello.jsp,可以在Servlet的service()方法中执行以下代码:

RequestDistpatherrd=request.getRequestDispather(“hello.jsp”);

//ForwardtorequestedURL

rd.forward(request.response);

在JSP页面中,可以使用

forward>转发请求,例如:

forwardpage=“hello.jsp”/>

对于请求转发,转发的资源组件和目标组件共享request范围内的共享数据。

7.1.1.2.请求重定向

请求重定向类似请求转发,但也有一些重要区别:

●Web组件可以将请求重定向到任一URL,而不仅仅是统一应用中的URL。

●重定向的资源组件和目标组件之间不共用一个HttpServletRequest对象,因此不能

●共享request范围内的共享数据。

下图显示了一个Serlet把请求重定向给另一个JSP组件的过程。

图7-3:

请求重定向

如果当前应用的Servlet组件要把请求转发给URL“http:

//jakarta.apache.org/struts”,可

以在Servlet的service()方法中执行以下代码:

response.sendRedirect(“http:

//jakarta.apache.org/struts”);从上图中可以看出,HttpServletResponse的sendRedirect()方法向浏览器返回包含重定向

信息,浏览器根据这一信息发送出一个新的HTTP请求,请求访问重定向目标组件。

7.1.1.3.包含

包含关系允许一个Web组件聚集来自同一个应用中其他Web组件的输出数据,并使用被聚集的数据来创建响应效果。

这种技术通常用于模板处理器,它可以控制网页的布局。

模板中每个页面区域的内容来自不同的URL,conger组成单个页面。

这种技术能够为应用程序提供一致的外观和感觉。

包含关系的源组件和目标组件共用同一个HttpServletRequest对象,因此他们共享request范围内的共享数据。

下图显示了一个Servlet包含另一个JSP组件的过程。

图7-4:

Web组件的包含关系

Servlet类使用javax.servlet.RequestDispather.include()方法包含其他Web组件。

例如,如果当前的Servlet组件包含了3个JSP文件:

header.jsp、main.jsp和footer.jsp,则可以在Servlet的service()方法中执行以下代码:

……

RequestDispatcherrd;

rd=req.getRequestDispatcher(“/header.jsp”);

rd.include(req,res);

rd=req.getRequestDispatcher(“/main.jsp”);

rd.include(req,res);

rd=req.getRequestDispatcher(“/footer.jsp”);

rd.include(req,res);

……

在JSP文件中,可以通过指令来包含其他Web资源,例如:

<%@includefile=“/header.jsp”%>

<%@includefile=“/main.jsp”%>

<%@includefile=“/footer.jsp”%>

7.1.2.MVC概述

模型-视图-控制器(MVC)是80年代Smalltalk-80出现的一种软件设计模式,现在已经被广泛的使用。

开发模式上采用Model-View-Controller(MVC)模式,MVC模式将程序代码整理切割为三部份,Model部分是业务与应用领域(Businessdomain)相关逻辑、管理状态之对象,Controller部分接收来自View所输入的资料并与Model部分互动,是业务流程控制(FlowControl)之处,View部分则负责展现资料、接收使用者输入资料。

●模型(Model)模型是应用程序的主体部分。

模型表示业务数据,或者业务逻辑.

●视图(View)视图是应用程序中用户界面相关的部分,是用户看到并与之交互的界面。

●控制器(controller)控制器工作就是根据用户的输入,控制用户界面数据显示和更新model对象状态。

 

图7-5:

MVC设计模式

7.1.2.1.MVC的优点

可以为一个模型在运行时同时建立和使用多个视图。

变化-传播机制可以确保所有相关的视图及时得到模型数据变化,从而使所有关联的视图和控制器做到行为同步。

视图与控制器的可接插性,允许更换视图和控制器对象,而且可以根据需求动态的打开或关闭、甚至在运行期间进行对象替换。

模型的可移植性。

因为模型是独立于视图的,所以可以把一个模型独立地移植到新的平台工作。

需要做的只是在新平台上对视图和控制器进行新的修改。

潜在的框架结构。

可以基于此模型建立应用程序框架,不仅仅是用在设计界面的设计中。

7.1.2.2.MVC的不足之处

增加了系统结构和实现的复杂性。

对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。

视图与控制器间的过于紧密的连接。

视图与控制器是相互分离,但确实联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。

视图对模型数据的低效率访问。

依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。

对未变化数据的不必要的频繁访问,也将损害操作性能。

目前,一般高级的界面工具或构造器不支持MVC模式。

改造这些工具以适应MVC需要和建立分离的部件的代价是很高的,从而造成使用MVC的困难。

7.1.2.3.MVC的应用范围

使用MVC需要精心的计划,由于它内部原理比较复杂,所以需要花费一些时间去理解它。

将MVC运用到应用程序中会带来额外的工作量,增加应用的复杂性,所以MVC部适合小型应用程序。

但是对于开发存在大量用户界面上,并且业务逻辑复杂的大型应用程序,MVC将会使软件在健壮性、代码重用喝结构方面上一个新台阶。

尽管在最初构建MVC框架时会花费一定工作量,但从长远的角度来看,它会大大提供后期软件开发效率。

7.1.3.JSPModel1和JSPModel2

SUN在JSP出现早期制定了两种规范,称为Model1和Model2。

图7-6:

JSPModel1

Model1它是以页面为中心的。

适用于完成简单的应用程序。

实现这个模式的应用程序有一系列的Jsp页面,在这些页面里用户程序运行从一个页面到另一个页面。

因为它的简单容易。

Model1应用的主要问题是难以维护,并且毫无灵活性可言。

另外,由于开发人员已经同时被卷入到了页面开发和商业逻辑的编码中,这个架构模式在页面设计人员和web开发人员之间很难实现劳动分工。

图7-7:

JSPModel2

JSPModel1和JSPModel2的本质区别在于处理用户请求的位置不同。

在Model1体系中,JSP页面负责响应用户请求并将处理结果返回用户。

JSP既要负责具体业务流程控制,又要负责提供表示层数据,同时充当视图和控制器,未能实现这两个模块之间的独立和分离。

尽管Model1体系十分适合简单应用的需要,它却不适合开发复杂的大型应用程序。

不加选择的使用Model1,会导致JSP页内嵌入大量Java代码。

尽管这对Java程序员不是多大的问题,但如果JSP页面由网页设计人员开发并进行维护的(大量的实际项目中情况确实是这样的),这个问题就会变得十分突出。

从根本上讲,将导致角色定义不清和职责分配不明,会给项目管理带来很大的麻烦。

JSPModel2体系结构是一种联合使用JSP和Servlet来提供动态内容服务的方法。

它吸取了JSP和Servlet两种技术各自的突出优点,用JSP生成表示层的内容,让Servlet完成深层次的处理任务。

在这里,Servlet充当控制器的角色,负责处理用户请求,创建JSP页需要使用的JavaBean对象,根据用户请求选择使用的JSP页返回给用户。

在JSP页内没有处理逻辑,它仅负责检索原先由Servlet创建的JavaBean对象,从Servlet中提取动态内容插入静态模板。

这是一种有突破性的软件设计方法,它清晰地分离了表达和内容,明确角色定义以及开发者与网页设计者的分工。

事实上,项目越复杂,使用Model2的好处越大,越容易体现。

7.1.4.Struts概述

Struts实质上就是在JSPModel2的基础上实现一个MVC框架。

在Struts框架中,模型由实现业务逻辑的JavaBean或EJB组件构成,控制器由ActionServlet和Action来实现,视图由一组JSP文件构成。

图7-8:

Struts实现的MVC框架

7.1.4.1.Model

Struts没有定义具体的Model层的实现,Model层通常是和业务逻辑紧密相关的,还通常有持续化的要求,Struts目前没有考虑到这一层,但是,不管在开源世界还是商业领域,都有一些都别优秀的工具可以为Model层次的开发提供便利,例如优秀的O/RMapping开源框架Hibernate。

7.1.4.2.View

通常,Web应用的UI由以下文件组成:

●HTML

●JSP

而JSP中通常包含以下组件:

●自定义标签

●DTO(DataTransferObject数据传输对象)

在Struts中,还包含了以下两种常用的组件:

●StrutsActionForms

●资源绑定(javaresourcebundles),例如将标签的显示内容,错误提示的内容通

过配置文件来配置,这样可以为实现国际化提供基础。

由此可见,Struts对于传统的WebUI所作的扩充就是StrutsActionForms和资源绑定,接下来对其进行进一步描述。

7.1.4.3.Controller

J2EE的前端控制器(FrontController)设计模式中利用一个前端控制器来接受所有客户请求,为应用提供一个中心控制点,在该控制点上,可以很方便地添加一些全局性的,如加密、国际化、日志等通用操作。

Controller的实现机制正是建立在前端控制器的设计模式基础上。

前面我们介绍过,Struts的控制器拥有一些职责,其中最主要的是以下几个:

1.1.接收客户请求。

2.2.映射请求到指定的业务操作。

3.3.获取业务操作的结果并以有效的方式提供给客户。

4.4.根据业务操作的结果和当前的状态把不同的UI推向给客户。

在Struts框架中,控制器中不同的组件负责不同的控制职责,下图是Struts框架中关于控制器部分的一个组件图:

图7-9:

控制器组件

在上图中,很明显地可以看出,ActionServlet处于核心位置,那么,我们就先来了解一下ActionServlet。

org.apache.struts.action.ActionServlet在Struts应用程序中扮演接收器的角色,所有客户端的请求在被其它类处理之前都得通过ActionServlet的控制。

当ActionServlet的实例接收到一个HTTP请求,不管是通过get方法或post方法,ActionServlet的process()方法被调用并用以处理客户请求。

process()方法实现显示如下:

protectedvoidprocess(HttpServletRequestrequest,HttpServletResponseresponse)

throwsIOException,ServletException{

RequestUtils.selectApplication(request,getServletContext());

getApplicationConfig(request).getProcessor().process(request,response);}

该方法的实现很简单,RequestUtils.selectApplication(request,getServletContext());语句是用来根据用户访问的上下文路径来选择处理的应用,如果你只有一个Struts配置文件,就表示你只有一个Struts应用。

getApplicationConfig(request).getProcessor().process(request,response);语句用来获取一个处理器,并将客户请求提交给处理器处理。

7.1.4.4.Struts初始化处理流程

根据在web.xml中配置的初始化参数,Servlet容器将决定在在容器的第一次启动,或第一次客户请求ActionServlet的时机加载ActionServlet,不管哪种方式加载,和其它Servlet一样,ActionServlet的init()方法将被调用,开始初始化过程。

让我们来看看在初始化过程中将发生些什么,理解了这些,对于我们debug和扩展自己的应用更加得心应手。

5.1.初始化框架的内部消息绑定,这些消息用来输出提示,警告,和错误信息到日志文件中。

org.apache.struts.action.ActionResources用来获取内部消息;

6.2.加载web.xml中定义的不同参数,用以控制ActionServlet的不同行为,这些参数包括config,debug,detail,andconvertNull;

7.3.加载并初始化web.xml中定义的servlet名称和servlet映射信息。

通过初始化,框架的各种DTD被注册,DTD用来在下一步校验配置文件的有效性;

8.4.为默认应用加载并初始化Struts配置文件,配置文件即初始化参数config指定的文件。

默认配置文件被解析,产生一个ApplicationConfig对象存于ServletContext中。

可以通过关键字org.apache.struts.action.APPLICATION从ServletContext中获取ApplicationConfig;

9.5.Struts配置文件中指定的每一个消息资源都被加载,初始化,并存在ServletContext的合适区域(基于每个message-resources元素的key属性),如果key属性没有设置,则为org.apache.struts.action.MESSAGE;

10.6.Struts配置文件中声明的每一个数据源被加载并且初始化,如果没有配置数据源,这一步跳过;

11.7.加载并初始化Struts配置文件中指定的插件。

每一个插件的init()方法被调用;

当默认应用加载完成,init()方法判断是否有应用模块需要加载,如果有,重复步骤4—7步成应用模块的加载。

7.1.4.5.Struts工作流程

图7-10:

Struts工作流程

上图是Struts的工作流程,前边我们提到,所有的请求都提交给ActionServlet来处理。

ActionServlet是一个FrontController,它是一个标准的Servlet,它将request转发给RequestProcessor来处理。

ActionMapping是ActionConfig的子类,实质上是对struts-config.xml的一个映射,从中可以取得所有的配置信息。

RequestProcessor根据提交过来的url,如*.do,从ActionMapping中得到相应的ActionForn和Action。

然后将request的参数对应到ActionForm中,进行form验证。

如果验证通过则调用Action的execute()方法来执行Action,最终返回ActionFoward。

ActionFoward是对mapping中一个foward的包装,对应于一个url。

ActionForm使用了ViewHelper模式,是对HTML中form的一个封装。

其中包含有validate方法,用于验证form数据的有效性。

ActionForm是一个符合JavaBean规范的类,所有的属性都应满足get和set对应。

对于一些复杂的系统,还可以采用DynaActionForm(Struts1.1)来构造动态的Form,即通过预制参数来生成Form。

这样可以更灵活的扩展程序。

ActionErrors是对错误信息的包装,一旦在执行action或者form.validate中出现异常,即可产生一个ActionError并最终加入到ActionErrors。

在Form验证的过程中,如果有Error发生,则会将页面重新导向至输入页,并提示错误。

Action是用于执行业务逻辑的RequsestHandler。

每个Action都只建立一个instance。

Action不是线程安全的,所以不应该在Action中访问特定资源。

一般来说,应改使用BusinessDelegate模式来对Businesstier进行访问以解除耦合。

Struts提供了多种Action供选择使用。

普通的Action只能通过调用execute执行一项任务,而DispatchAction可以根据配置参数执行,而不是仅进入execute()函数,这样可以执行多种任务。

如insert,update等。

LookupDispatchAction可以根据提交表单按钮的名称来执行函数。

当ActionServlet接收到一个客户请求时,将执行如下流程:

图7-11:

Struts响应用户请求的工作流程

1)检索和用户请求匹配的ActionMapping实例,如果不存在,就放回用户请求路径无效的信息。

2)如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中。

3)根据配置信息决定是否需要表单验证。

如果需要验证,就调用ActionForm的

validate()方法。

4)如果ActionForm的validate()方法返回null或者一个不包含ActionMessage的

ActionErrors对象,就表示表单验证成功。

验证不成功则发送给用户提交表单的

JSP组件,或者转向其他组件。

这样Action对象不会被创建。

5)ActionServlet根据ActionMapping实例包含的映射信息决定将请求转发给哪个

Action。

如果相应的Action实例不存在,就先创建这个实例,然后调用Action的execute()方法。

6)Action的execute()方法返回一个ActionForward对象,ActionServlet再把客户

请求转发给ActionForward对象只想JSP组件。

7)ActionForward对象指向JSP组件生成动态网页,返回给客户。

 

7.2.从helloapp开始Struts应用

7.2.1.helloapp的需求

helloapp的需要非常简单,主要是体验Struts开发过程,其内容如下:

●接收用户输入姓名,然后返回字符串“Hello

”。

●如果用户没有输入姓名就提交表单,将返回错误信息,提示用户首先输入姓名。

●如果用户输入姓名为“Monster”,将返回出错信息,拒绝向“Monster”sayhello。

●为了演示模型组件的功能,本应用使用模型组件来保护用户输入的姓名。

7.2.2.组建Struts框架

Helloapp应用的各个模块组成:

JavaBean组件:

PersonBean,有一个userName属性,代表用户输入的名字。

提供了get/set方法。

这里可以预留save()方法,将数据保存到数据库中(JavaBean组件可以作为EJB或者Web服务前端组件)。

视图:

hello.jsp,提供用户界面,接收用户输入的姓名。

视图还包括一个ActionFormBean,它用来存放表单数据,并进行表单验证。

控制器:

Action类HelloAction,主要任务有,一、进行业务逻辑验证,如果用户输入姓名为“Monster”,将返回错误消息;二、调用模型组件PersonBean的save()方法,保存用户输入的名字;三、决定将合适的视图组件返回给用户。

除了以上的模块,我们还要创建Struts

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1