基于mvc的java web设计与开发

第1章 struts与java web应用简介
1.1 java web应用概述
1.2 web组件的三种关联关系
1.3 muv概述
1.4 struts概述
1.4.1 struts实现mvc的机制
在struts框架中,模型由实现业务逻辑的javabean或ejb组件构成,控制器由

ActionServlet和Action类实现,视图由一组jsp文件构成。

1.视图
视图就是jsp文件。在这些jsp文件中没有业务逻辑,也没有模型信息,只有标签。
通常把struts框架中的ActionForm bean 也划分到视图模块中。struts框架利用ActionForm

bean来进行视图和控制器之间表单数据的传递。struts框架把用户输入的表单数据保存在

ActionForm bean中,把它传递给控制器,控制器可以对ActionForm bean中的数据进行修改,

jsp文件使用struts标签读取修改后的ActionForm bean的信息。重新设置html表单。

2.模型
模型表示应用程序的状态和业务逻辑。业务逻辑通常由javabean或ejb组件来实现。

3.控制器
控制器由ActionServlet类和Action类来实现。ActionServlet类是struts框架中的核

心组件。ActionServlet继承了javax.servlet.http.HttpServlet类,它在mvc模型中扮演控制

器的角色。ActionServlet主要负责接收http请求信息,根据配置文件struts-config.xml的配

置信息,把请求转发给适当的Action对象。如果该Action对象不存在,ActionServlet会先创建

这个Action对象。

Action类负责调用模型的方法,更新模型的状态,并帮助控制应用程序的流程。对于

小型的应用,Action类本身也可以完成一些实际的业务逻辑。

对于大型应用,Action充当用户请求和业务逻辑处理之间的适配器(Adaptor),其功能就是将

请求与业务逻辑分开,Action根据用户请求调用相关的业务逻辑组件。业务逻辑组件由

javabean或者ejb组件来完成,Action类侧重与控制应用程序的流程,而不是实现应用程序的逻

辑。通过将业务逻辑放在单独的java包或ejb中,可以提高应用程序的灵活性和可重用性。

当ActionServlet控制器收到用户请求后,把请求转发到一个Action实例。如果这个实

例不存在,控制器会首先创建它,然后调用Action实例的execute()方法。Action的execute

()方法返回一个ActionForward对象,她封装了把用户请求再转发给其他web组件的信息。用

户定义自己的Action类,即Action基类的子类时,必须覆盖execute()方法。在Action基类中

该方法返回null。

1.4.2 struts的工作流程

当ActionServlet接收到一个客户的请求时,将执行如下流程:
1.检索和用户请求匹配的ActionMapping实例,如果不存在,就返回用户请求路径无效信息。
2.如果ActionForm实例不存在,就创建一个Actionform对象,把客户提交的表单数据保存到

ActionForm对象中。
3.根据配置信息决定是否需要表单验证。如果需要验证,就调用ActionForm的validate()方

法。
4.如果ActionForm的validata()方法返回null或返回一个不包含ActionMessage的

ActionErrors对象,就表示表单验证成功。
5.ActionServlet根据ActionMapping实例包含的映射信息决定将请求转发给哪个Action。如果

相应的Action实例不存在,就会创建这个实例,然后调用Action的execute()方法。
6.Action的execute()方法返回一个ActionForward对象,ActionServlet再把客户请求转发给

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


第2章 struts应用:helloapp应用

 


第5章 struts控制器组件
struts控制器组件负责接受用户请求,更新模型,以及选择合适的视图组件返回给用

户。控制器组件有助于将模型层和视图层分离。

struts控制器组件主要包括:
ActionServlet组件:充当strtus框架的中央处理器
RequestProcessor组件:充当每个子应用模块的请求处理器
Action组件:负责处理一项具体的业务

strtus框架采用ActionSerblet和RequestProcessor组件进行集中控制,并采用Action组件来

处理单项业务。

5.1 控制器组件的控制机制
struts的控制器组件主要完成以下任务:
a、接收用户请求
b、根据用户请求,调用合适的模型组件来执行相应的业务逻辑
c、获取业务逻辑执行结果
d、根据当前状态以及业务逻辑执行结果,选择合适的视图组件返回给用户

5.1.1 ActionServlet类
org.apache.struts.action.ActionServlet类是struts框架的核心控制器组件,所有的用户请

求都先有ActionServlet来处理,然后在由ActionServlet把请求转发给其他组件。

strtus框架只允许在一个应用中配置一个ActionServlet类,在应用的生命周期中,仅创建

ActionServlet类的一个实例,这个ActionServlet实例可以同时响应多个用户请求。

1.struts框架初始化过程
servlet容器在启动时,或者用户首次请求ActionServlet时加载ActionServlet类。在

这2种情况下,servlet容器都会在ActionServlet被加载后立即执行它的init()方法,这可以

保证当ActionServlet处理用户请求时已经被初始化。

2.ActionServlet的process()方法
当ActionServlet实例接受到http请求后,在doGet()方法或doPost()方法中都会调用

processs()方法来处理请求。


3.扩展ActionServlet类

5.1.2 RequestProcessor类
对于多应用模块的struts应用,每个子应用模块都有各自的RequestProcessor实例。

在ActionServlet的process()方法中,一旦选择了正确的子应用模块,就会调用子应用模块

的Requestprocessor实例的process()方法来处理请求。在ActionServlet调用这个方法时,

会把当前的request和response对象传给它。

struts框架只允许应用中存在一个ActionServlet类,但是可以存在多个客户化的

RequestProcessor类,每个子应用模块都可以拥有单独的
RequestProcessor类。如果想修改RequestProcessor类的一些默认功能,可以覆盖

RequestProcessor基类中的相关方法。

1.RequestProcessor类的process()方法。
RequestProcessor类的process()负责实际的预处理请求操作。

2.扩展RequestProcessor类


5.1.3 Action类

Action类是用户请求和业务逻辑之间的桥梁。每个Action充当客户的一项业务代理。在

RequestProcessor类预处理请求时,在创建了Action实例后,就调用自身的

processActionPerform()方法,该方法在调用Action类的execute()方法。


Action的execute()方法调用模型的业务方法,完成用户的业务逻辑,然后根据执行结果把请

求转发给其他合适的web组件。
1.Action类缓存
为了确保线程安全,在一个应用的生命周期中,struts框架只会为每个Action类创建一个

Action实例。所有的客户请求共享一个Action实例,并且所有请求线程可以同时执行她的

execute()方法。

RequestProcessor类包含一个HashMap,作为存放所有Action实例的缓存,每个Action实例在缓

存中存放的属性key为Action类名。在RequestProcessor类的processActionCreate()方法中,

首先检查在HashMap中是否存在Action实例,如果存在,就返回这个实例;否则,就创建一个新

的Action实例。创建Action实例的代码位于同步代码块中,以保证只有一个线程创建Action实

例。一旦线程创建了Action实例并把它放到HashMap只,以后所有的线程都会直接使用这个缓存

中的实例。

2.ActionForward类
Action类的execute()方法返回一个ActionForward对象。ActionForward对象代表了web资源

的逻辑抽象,这里的web资源可以是jsp页,java servlet或action。从execute()方法中返回

ActionForward对象有2种方法:
a、在execute()方法只动态创建一个ActionForward实例:
return new ActionForward("Failure","/secruity/singnin.jsp",true);
以上ActionForward构造方法的第一个参数代表ActionForward实例的逻辑名,第2个参数指定转

发路径,第3个参数指定是否进行重定向。

b、在struts配置文件中配置<forward>元素:

    <action    path      = "/singin"
               type      = "netstore.security.LoginAction"
               name      = "loginForm"
               scope     = "request"
               validate = "true"
               input     = "/security/signin.jsp"
     >
        <forward name="Success" path="/action/home" />
<forward name="Failure" path="/security/signin.jsp" redirect="true"/>
    </action>

配置了<forward>元素后,在sturts框架初始化时,就会创建存放<forward>元素配置信息的

ActionForward对象。

P110


3.创建支持多线程的Action类
在struts应用的生命周期中,只会为每个Action类创建一个实例,所有的客户请求共

享这个实例 。因此必须保证在多线程环境中,Action也能正常工作。保证线程安全的重要原则

是在Action类中仅仅使用局部变量,谨慎使用实例变量。

如果在Action的execute()方法中定义了局部变量,对于每个调用execute()方法

的线程,jvm会在每个线程的堆栈中创建局部变量,因此每个线程拥有独立的局部变量,不会被

其他线程共享。当线程执行完executive()方法是,它的局部变量就会被销毁。

如果在Action类中定义了实例变量,那么在Action实例的整个生命周期中,这个实例

变量被所有 的请求线程共享。因此不能在Action类中定义代表特点客户状态的实例变量,例如

不能定义购物车实例变量,因为每个用户拥有各自不同的购物车。

在Action类中定义的实例变量代表了可以被所有请求线程访问的共享资源。为了避免

共享资源的竞争,在必要的情况下,需要采用java同步机制对访问共享资源的代码块进行同步

 

4.Action类的安全
在某些情况下,如果Action类执行的功能非常重要,则只允许特点权限的用户才能访问Action

。为了防止未授权的用户来访问Action,可以在配置Action时指定安全角色。

P111

5.2使用内置的struts Action类
最常见的Action类为:
org.apache.struts.actions.ForwardAction
org.apache.struts.actions.IncludeAction
org.apache.struts.actions.DispatchAction
org.apache.struts.actions.LookupDispatchAction
org.apache.struts.actions.SwitchAction

5.2.1 org.apache.struts.actions.ForwardAction类 P112
如果仅仅需要Action类提供请求转发功能,则可以使用

org.apache.struts.actions.ForwardAction类。ForwardAction类专门用于转发请求,不执行

任何其他的业务操作。

ActionServlet把请求转发给ForwardAction,ForwardAction再把请求转发给<action>元素中的

parameter属性指定的web组件。总之,在web组件之间通过ForwardAction类来进行请求转发,

可以充分利用struts控制器的预处理请求功能。

此外,也可以通过action元素的forward属性来实现请求转发,以下代码能完成同样功能:
    <action    path      = "/viewsignin"
               forward   = "/security/signin.jsp"
               name      = "loginForm"
               scope     = "request"
               validate = "false"
               input     = "index.jsp"
     >
    </action>


5.2.2 org.apache.struts.actions.IncludeAction类 p114

5.2.3 org.apache.struts.actions.DispatchAction类
通常,在一个Action类中只能完成一种业务操作,如果希望在同一个Action类中完成一组相关

的业务操作,可以使用DispatchAction类。

创建一个扩展DispatchAction类的子类,不必覆盖execute()方法,而是创建一些实现实际业

务操作的方法这些业务方法都应该和execute()方法具有同样的方法签名,即他们的参数和返

回类型的哦应该相同,此外也应该声明抛出Exception。


5.2.4 org.apache.struts.actions.LookupDispatchAction类
LookupDispatchAction类是DispatchAction的子类,在LookupDispatchAction类中也

可以定义多个业务方法。通常LookupDispatchAction主要应用于在一个表单中有多个提交按钮

,而这些按钮又有一个共同的名字的场合,这些按钮的名字和具体的ActionMapping的

parameter属性值相对应。

5.2.5 org.apache.struts.actions.SwitchAction类
SwitchAction类用于子应用模块之间的切换。

5.3 利用Token解决重复提交 p121


5.4 实用类

 

 

第6章 struts 模型组件

6.1 模型在mvc中的地位
struts应用的各个层次直接的依赖关系:
从上倒下:视图层 - 控制层 - 模型层 - 持久层 - 网络层
从上倒下依赖关系加强;从下到上依赖关系减弱

6.2 模型的概念和类型
6.2.1 概念模型
在简历模型之前,首先要对问题进行详细分析,确定用例,接下来就可以根据用例来

创建概念模型。概念模型用例模拟问题域中的真实实体。概念模型描述了每个实体的概念和属

性,以及实体之间的关系。但在这个阶段并不描述实体的行为。
创建概念模型的目的是帮助更好地理解问题域,识别系统中的实体,这些实体在设计

阶段很有可能变为类。

6.2.2 设计模型
概念模型是在软件分析阶段创建的,她帮助开发人员对应用的需求获得清晰明确的理

解。在软件设计阶段,需要在概念模型的基础上创建设计模型。可以用uml类框图,活动图以及

状态图来描述设计模型。

1. 关联(Associaion)
关联是类之间的引用关系。例如订单类对象OrderBO需要引用CustomerBO对象,来表明这个订单

是由那个客户发出的。如果类A引用类B,那么被应用的类B将被定义为类A的属性。

2. 依赖(Dependency)
依赖是是类之间的访问关系。如果类A引用类B的属性或方法,那么可以说类A依赖类B。与关联

关系不同的是,无需把类B定义为类A的属性。

3. 累积(Aggregation)
累积是指整体与个体之间的关系,可以把积累看作一种强关联关系。例如:购物车

ShoppingCart和购物条目ShoppingCartItem之间就是积累关系。一个购物车包括多个购物条目

。如果类A和类B之间存在累积关系,那么在类A中会定义一个集合属性,来存放类B对象。例如

,在ShoppingCart中定义了addItem()方法和removeItem()方法,用例向List中加入或删除

ShoppingCartItem对象。

4.一般化(Generalization)
一般化指类之间的继承关系。


6.3 业务对象(business object:BO)
BO是对真实世界的实体的软件抽象。她可以代表业务领域中的人,地点,事物或概念
BO包括状态和行为。

6.3.1业务对象的特征和类型
如果一个类可以作为业务对象,它应具有以下特征:
a、包含状态和行为
b、代表业务领域的人,地点,事物,概念
c、可以重用

bo可以分为3种类型:
a、实体业务对象
实体业务对象可以代表人,地点,事物或概念。通常把业务领域中的名词,例如:客

户,订单,商品等作为实体业务对象。

b、过程业务对象
过程业务对象代表应用中的业务过程或流程,他们通常依赖与实体业务对象。可以把

业务领域中的动词,例如:客户发出订单,登入应用等作为过程业务对象。

c、事件业务对象
事件业务对象代表应用中的一些事件(例如异常,警告,超时)。这些事件通常由系

统中的某种行为触发。

6.3.2业务对象的重要性
在应用中使用业务对象有许多好处,最重要的一点就是业务对象提供了通用的术语和

概念,不管是技术人员还是非技术人员都可以共享并理解他们。
此外,业务对象可以隐藏实现细节,对外只暴露接口。


6.4 业务对象的持久化

6.4.1对业务对象进行持久化的作用

6.4.2数据访问对象(DAO)设计模式
对象-关系的映射(object-Relation Mapping,简称orm)是一种耗时的工作,围绕对象-关系

和持久化数据的访问,在软件领域中发展起来了一种数据访问对象(Data Access Object,简

称DAO)设计模式。

DAO模式提供了访问关系型数据库系统所需要的所有操作的接口,其中包括创建数据库,定义表

,字段,索引,简历表间的关系,更新和查询数据库等。

DAO模式将底层数据库访问操作与高层业务逻辑分离开,对上次提供面向对象的数据访问接口。


ORM框架是一种持久化框架。DAO是用于实现持久化框架的一种设计模式。

 

 


第7章 struts视图组件

7.1视图概述
视图是模型的外在表现形式,用户通过视图来了解模型的状态。
7.2 在视图中使用javabean
7.2.1 DTO数据传输对象
DTO:Data Transfer Object。DTO用于在不同层之间传递数据。例如:可以在模型层与视图层

之间通过DTO传递数据。
没有把模型层的业务对象直接传递到视图层,而是通过DTO来传输数据,这样做有2个

好处:
a、减少传输数据的冗余,提供传输效率。
b、有助于实现各个层之间的独立,使每个层分工明确。

7.2.2 struts框架提供的DTO:ActionForm Bean
ActionForm bean是struts框架提供的DTO,用于在视图层和控制层之间传递html表单

数据。控制层可以从ActionForm bean中读取用户输入的表单数据,也可以把来自模型层的数据

存放到ActionForm bean中,然后把它返回给视图。

7.3使用ActionForm

7.3.1ActionForm的生命周期

控制器接受到请求 - 从request或session范围中取出ActionForm实例,如果该实例不存在,就

自动创建一个新的实例 - 调用ActionForm的reset()方法 - 把ActionForm实例保存在

request或session范围中 - 把用户输入的表单数据组装到ActioinForm中 - 如果<action>

的validate属性为true,则调用ActionForm的validate()方法   - "存在验证错误" - 把请求

转发给<action>的input属性指定的web组件,ActoinForm实例依然保存在request或session范

围内 - "无验证错误" - 调用Action的execute()方法,把ActionForm实例传递给execute()方

法 - 把请求转发给其他web组件,ActionForm实例依然保存在request或session范围内


ActionForm中的validate()方法:
如果struts的配置文件满足以下2个条件,struts控制器就会调用ActionForm的validate()方法


1.为ActionForm配置了Action映射,即<form-bean>元素的name属性和<action>元素的name属性

匹配
2.<action>元素的validate属性为true


在ActionForm基类中定义的validate()方法直接返回null,如果创建了扩展ActionForm基类的

子类,那么应该在子类中覆盖validate()方法。

validate()方法返回ActionErrors(或者ActionMessages)对象,如果返回的对象为null,或

者不包含任何ActionErrors(或者ActionMessages)对象,就表示没有错误,数据验证通过。

如果ActionErrors中包含ActionMessage对象,就表示发生了验证错误。

validate()方法主要负责检查数据的格式和语法,而不负责检查数据是否符合业务逻辑。例如

:html表单的文本域只能处理字符串类型的数据,所以在ActionForm中可以把年龄,数量等定

义为字符串类型属性,如何在validate()方法中进行验证,判断是否可以把用户输入的年龄,

数量转换为有效的数字。


ActionForm中的reset()方法:
不管Actionform存在于那个范围内,对于每个请求,控制器都会先调用ActionForm的reset()方

法,然后在把用户输入的表单数据组装到ActionForm中。reset()方法用于恢复ActionForm的

属性的默认值。

如果ActionForm在request范围内,那么对于每个新的请求都会创建新的ActionForm实例。当新

的实例创建后,如果它的属性已经被初始化为默认值,那么接着在在reset()方法中把属性设

置为默认值不是很有必要。因次在这种情况下,可以让reset()方法为空。
对于session范围内的ActionForm,同一个ActionForm实例会被多个请求共享,reset()方法

在这种情况下极为有用。

7.3.4访问ActionForm
ActionForm可以被jsp,struts标签,Action和其他web组件访问。访问ActionForm大致有以下

一些方法:
1.使用strtus HTML 标签库
<html:form>标签能够和ActionForm交互,读取ActionForm的属性值把他们赋值给表单

中对应的字段。
2.从request或session范围内取出ActionForm实例
strutrs框架把ActionForm实例保存在HttpServletRequest或HttpSession中,保存时

采用的属性Key为<form-bean>元素的name属性。因此如果ActionForm在request范围内,则可以

调用HttpServletRequest的getAttribue()方法读取ActionForm实例。例如:
LoginForm loginForm = (LoginForm)request.getAttribute("loginForm");
如果ActionForm在session范围内,则可以调用HttpSession的getAttribue()方法读

取ActionForm实例。例如:
LoginForm loginForm = (LoginForm)session.getAttribute("loginForm");
3.在Action类的execute()方法中直接访问ActionForm
如果配置了ActionForm和Action的映射,struts框架就会把ActionForm作为参数传递

给Action的execute()方法,因此在Action类的execute()方法中可以读取或设置

ActionForm属性。
public ActionForward execute(ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response) throws Exception{
String mail = ((LoginForm)form).getEmail();
String pwd = ((LoginForm)form).getPassword();
}


7.3.5处理表单跨页


7.4使用动态ActionForm

ActionForm的唯一缺点就是对于大型的struts应用,必须以编程的方式创建大量的ActionForm

类,如果html表单的字段发生变化,就必须修改并重新编译相关的ActionForm类。

struts1.1对此做了改进,引入了动态ActionForm类的概念。struts框架的DynaActionForm类及

其子类实现了动态ActionForm,DynaActionForm类是ActionForm的子类。
7.4.1配置动态ActionForm


7.4.2动态的ActionForm的reset()方法
DynaActionForm基类提供了initialize()方法,它把表单的所有属性恢复为默认值。表单属

性默认值由<fomr-bean><form-property>子元素的initial属性决定。如果没有设置initial属

性,则表单属性的默认值由其java类型来自动决定,例如对象类型的默认值为null,整数类型

的默认值为0,boolean类型的默认值为false。
DynaActionForm基类的reset()方法不执行任何操作。

如果希望struts框架在每次把表单数据组装到动态ActionForm中之前,先把所有的属性恢复为

默认值,可以定义一个扩展DynaActionForm类的子类,然后覆盖reset()方法,在reset()

方法中只要调用initalize()方法即可。

7.4.3访问动态ActionForm
Action类和jsp都可以访问动态ActionForm,使用方法与标准ActionForm大致相同,只有一点小

差别。
如果使用标准的ActionForm对象,在标准ActionForm中针对每个属性都提供了get、set方法,

来读取和设置属性,例如对email属性,应该提供了getEmail()和setEmail()方法。

而DynaActionForm把所有的属性保存在一个Map类对象中,并提供了下面勇于访问所有属性的通

用方法:
public Object get(Sring name)
public void set(String name,String value)

get(String name)方法根据指定的属性名返回属性值;
set(String name,String value)方法用于为定的属性赋值。
//get email
String email = (String)form.get("email");
//set email
form.set("email","xxx@162.com");


7.4.4动态ActionForm的表单验证
DynaActionForm基类的validate()方法没有提供任何默认的验证行为。可以定义扩

展DynaActionForm的子类,然后覆盖validate()方法,但是以编程的方式来验证动态

ActionForm违背了struts框架提供动态ActionForm的初衷,即以配置来替代编程。

幸运的是,可以采用另一种验证机制,即validator框架来完成验证。validator框架允许采用

特定的配置文件来为动态ActionForm配置验证规则。

7.4.5应用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值