- 浏览: 707542 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (272)
- Struts1.x (7)
- 事务 (2)
- Hibernate (11)
- 数据库 (14)
- JavaScript&Ajax (43)
- JSP&Servlet (2)
- Flex (1)
- 其它 (9)
- Java (22)
- 框架集成 (1)
- WebService (3)
- Tomcat (3)
- 加密和安全登录 (13)
- 基于原型的JavaScript (0)
- JavaDoc和Java编码规范 (3)
- CAS (1)
- 加密 (1)
- Axis2 (10)
- Ext2.x (3)
- SSH整合 (2)
- Ext (0)
- 正则表达式 (1)
- 设计模式 (4)
- 对象序列化技术 (3)
- CVS (2)
- Struts2 (6)
- Spring 2.x (7)
- Spring Security (2)
- Java 课程 (20)
- 程序员之死 (1)
- 软件测试 (6)
- UML (5)
- NetBeans (1)
- cxf (1)
- JMS (13)
- 设计 (5)
- ibatis2.x (3)
- Oracle (1)
- WebSphere (7)
- 概要设计 (1)
- DB2 (10)
- PowerDesigner (0)
- 软件工程 (5)
- rose (1)
- EA (1)
- LDAP (7)
- Portal&Portlet (3)
- MQ (10)
- ESB (4)
- EJB (2)
- JBoss (2)
最新评论
-
typeRos:
只有配置文件,没有代码么大神
Spring实现IBMMQ的JMS消息发布/订阅模式 -
panamera:
如果ActiveMQ服务器没有启动,这个时候消息生产者使用Jm ...
Spring JMSTemplate 与 JMS 原生API比较 -
lian819:
顶1楼, 引用文件, 配置属性, 太方便了
EXTJS 同步和异步请求 -
wilhard:
说得清楚明白
<%@ include file=""%>与<jsp:include page=""/>区别 -
刘琛颖:
总结的很好。受益了
javascript 父窗口(父页面)— 子窗口 (子页面)互相调用的方法
Web组件的三种关联关系
- 请求转发
- URL重定向
- 包含
存在以上关联关系的Web组件可以是JSP或Servlet,对于Struts应用,则还包括Action。这些Web组件都可以访问HttpServletRequest和HttpServletResponse对象,具有处理请求、生成响应结果的功能。
1、请求转发
请求转发的代码:
request.getRequestDispatcher(“hello.jsp”).forward(request, response);
之所以要将request和response当做forward方法的参数,正说明转发与被转发的Web组件之间使用的是同一个request对象.
在JSP页面中, 可以使用<jsp:forward>标签来转发请求, 例如:
<jsp:forward page=”hello.jsp”/>
对于请求转发, 转发的源组件和目标组件共享request范围内的共享数据.
2、URL重定向
URL重定向与请求转发相似, 但也有着本质的不同
- Web组件可以将请求重定向到任一UL, 而不仅仅是同一应用中的URL.
- 重定向的源组件和目标组件之间不共用同一个HttpServletRequest对象, 因此不能共享request范围内的共享数据
如果当前应用的Servlet组件要把请求转发给URL “http://localhost:8080/asp1.1”,可以在Servlet的service()方法中执行以下代码:
response.sendRedirect(“http://localhost:8080/asp1.1”);
3、包含
包含关系允许一个Web组件聚集来自同一个应用中其他Web组件的输出数据,并使用被聚集的数据来创建响应结果. 包含关系的源组件和目标组件共用同一个HttpServletRequest对象, 因此它们共享request范围内的共享数据.
Servlet类使用javax.servlet.RequestDispatcher.include()方法包含其他的Web组件. 例如, 如果当前的Servlet组件包含了三个JSP文件: header.jsp、main.jsp和footer.jsp, 则可以在Servlet的service()方法中执行以下代码:
RequestDispatcher rd;
rd = req.getRequestDispatcher(“/header.jsp”);
rd.include(req, res);
rd = req.getRequestDispatcher(“/main.jsp”);
rd.include(req, res);
rd = req.getRequestsDispatcher(“/footer.jsp”);
rd.include(req, res);
在JSP文件中, 可以通过<include>指令来包含其他的Web资源, 例如:
<%@ include file=”header.jsp”%> <%@ include file=”mainjsp”%> <%@ include file=”footer.jsp”%>
图4、MVC Model 1
图5、MVC Model 2
Model 1 与 Model 2 的区别,Model 2 下 JSP 不再承担控制器的责任,它仅仅是表现层角色,仅仅用于将结果呈现给用户,JSP页面的请求与Servlet(控制器)交互,而Servlet负责与后台的JavaBean通信。在Model 2 模式下,模型(Model)由JavaBean充当.
Struts,MVC 2 的一种实现
图6 Struts 实现的MVC框架
表现层框架 设计模式 struts mvc模式
Struts是Java MVC WEB开发框架的事实标准,网上看了很多关于Struts组件在MVC模式中的划分,着实让初学Struts的我感到很混乱.
其中争议最多的是ActionForm,有人说它是属于Model层,有人把它归为View,我倾向把ActionForm归属于Model,因为ActionForm是和数据打交道的,在V和C中传输数据的桥梁,但是比起在Struts+Spring+hibernate架构中的Model,Dao之类的,把他称为模型感觉有点不合适.
再有就是Action了,有的把它归为M,有的是C,理论上来说Action因该属于C,但是想想ActionServlet,它才是老板,决定处理请求的Action,Action只是和业务层沟通,我觉得Action还是属于C层,毕竟它还要完成最后JSP页面的跳转控制和为V层准备数据,但是有时候在Action中写太多的业务逻辑的话,又感觉它有点像M,哎,郁闷啊,毕业设计做了个MVC的系统,现在对它的分层还不是很理解,答辩的时候不知道怎么去说啊
fw2003
发表文章: 12
注册时间: 2007年05月23日 08:57
悄悄话
个人博客
re:关于Struts中MVC划分的疑问? 2007年05月28日 08:25
一般来说 actionservlet是控制器 而action是真正的业务实现者 也就是在action中调用相应的业务逻辑组件来完成数据交互 这样的话action应该也属于c
但是一般的小型应用 业务逻辑层的东西很少的话 也都是写在action里的
以上是我个人看法
coolzyt
发表文章: 10
注册时间: 2007年04月15日 09:05
悄悄话
个人博客
re:关于Struts中MVC划分的疑问? 2007年05月28日 10:17
struts实现了MVC,actionform是model,action是c
加上Spring,hibernate就是多层架构了,又有新的model,但和mvc就没关系了
zhaochunhui
发表文章: 1
注册时间: 2007年05月28日 09:53
悄悄话
个人博客
re:关于Struts中MVC划分的疑问? 2007年05月28日 10:31
actionfrom 是对应 view(如:jsp)的module,也就是form中有什么 actionform中就有什么 ,而不是对应持久层的,当页面流程出现变化 actionform也会出现变化 它不应该被传递到 业务层否则代码会出现相当大的改动
而action应该是 控制层(Control),里面不应该写过多的业务代码 它应该起到桥梁的作用
hwangita
发表文章: 21
注册时间: 2007年03月27日 22:52
悄悄话
个人博客
re:关于Struts中MVC划分的疑问? 2007年06月03日 18:16
action应该是c啊,actionservlet是全局的,毫无疑问。
其实,我觉得,你吧整个流程搞清楚了,何必苦苦执着于M,V,C呢?
我的理解,一般开发时,在Struts配置文件里先写,
顺数大都这样,
先从jsp页面开始,经过actionform把数据取出来传给action,这里面有简单的业务处理,其实,真正的业务处理应该是在javabean中,action最后还要负责跳转,
而全局的控制器就是actionservlet。
所以,我觉得,局限于action和actionform的层次,是浪费你的精力,关注点不再这里!
ljw714
发表文章: 16
注册时间: 2006年05月02日 16:00
悄悄话
个人博客
re:关于Struts中MVC划分的疑问? 2007年06月06日 17:37
actionform 是属于v层,它并不是进行数据持久化的.如你使用的是纯Struts的话,也就是说你把数据访问都写在action中,那action既是c层又是m层了.一般是会写数据访问类DAO的.其实现在使用Struts+spring+hibernate,整个Struts的东西动被看做是v层的.这是我的理解.
fw2003
发表文章: 12
注册时间: 2007年05月23日 08:57
悄悄话
个人博客
re:关于Struts中MVC划分的疑问? 2007年06月13日 18:11
将J2EE的分层体系简单的认为是MVC 我觉得是错误的
J2EE大体分为 WEB层 业务层 持久层
那么MVC只是WEB层的实现模式而已
而Struts正是这样一种体现MVC模式的框架,也就是说你的系统的整个WEB层都由Struts来构建 而Hibernate则负责构建持久层
jacshan
发表文章: 17
注册时间: 2006年09月14日 20:32
悄悄话
个人博客
回复:re:关于Struts中MVC划分的疑问? 2007年06月14日 21:56
现在就是相对于Struts的MVC中,MVC分别是对应Struts的哪几个组件?
当然在Struts+Spring+Hibernate的架构中,那M应该是由Spring管理的业务层组件还有就是DAO接口和 其实现类吧
banq
发表文章: 10146
注册时间: 2002年08月03日 17:08
悄悄话
个人博客
回复:回复:re:关于Struts中MVC划分的疑问? 2007年06月15日 16:39
>现在就是相对于Struts的MVC中,MVC分别是对应Struts的哪几个组件?
Struts的Action属于MVC的C (controller); Struts的标签+html的JSP属于V(View),而ActionForm可以看成是Model的一个映射,在Struts2.0中Model可以直接作为Struts的ActionForm,MVC的M还有表示业务层Model的意思。
gougou3250
发表文章: 98
注册时间: 2007年05月08日 16:48
悄悄话
个人博客
re:关于Struts中MVC划分的疑问? 2007年06月15日 18:16
用Struts2吧 么有actionForm
jacshan
发表文章: 17
注册时间: 2006年09月14日 20:32
悄悄话
个人博客
re:关于Struts中MVC划分的疑问? 2007年06月15日 23:58
呵呵,明天答辩了,论文上是参考IBM上的几篇Struts的,他们是把Actoin做为Model
其实这分做什么并不是很重要,但是答辩嘛,还是的有个明确的说法的
[该贴被jacshan于2007年06月15日 23:59修改过]
gougou3250
发表文章: 98
注册时间: 2007年05月08日 16:48
悄悄话
个人博客
re:关于Struts中MVC划分的疑问? 2007年06月16日 08:52
action应该是control吧,不应该是module
boyszz
发表文章: 15
注册时间: 2007年09月09日 04:22
悄悄话
个人博客
re:关于Struts中MVC划分的疑问? 2007年09月09日 04:56
ActionForm是属于Model层的,毫无疑问。
需要提一下的是,WEB架构里是不存在MVC这样的架构的,MVC架构的名词起源于富客户端.
Model,即是你的领域对象,比如你的程序是展现一个人的基本信息,那这个领域对象就应该是Person这个类.(Struts需要领域对象继承ActionForm来自动把表单数据映射到对象,我想应该没有人会觉得这是个好的设计.)
Controller,是你的控制器,通常是根据用户的行为,执行改变你的领域对象操作.
View,是你的展现层,决定怎样的方式展现你的领域对象,比如你希望通过一个表格来展现,那这个表格就应该由View层来画.
MVC,是指当用户执行动作,Controller使Model发生改变,View层自动更新Model对象,而这在WEB应用里是不可能的.因为http连接是无状态的.不过因为两者的区别也不是太大,所以还是经常用MVC来代替WEB的架构体系.
[该贴被boyszz于2007年09月09日 04:59修改过]
hiworld
发表文章: 23
注册时间: 2007年09月09日 17:37
悄悄话
个人博客
re:关于Struts中MVC划分的疑问? 2007年09月09日 19:42
我个人认为这个问题应该分开来说,针对不同的应用,担任不同的角色.在多层次的结构中.有的时候部分业务在其他层次中实现更加简便.因为在设计阶段就离散部分业务逻辑.因此为业务逻辑有时会渗透甚至融合到表示层和持久层.这一现象针对简单需求而产生的结构退化.或者是对特殊需求的正确权衡.一般来说,action是C层,但如果里面参入了太多的业务逻辑的话.就是M层了.而actionform有时候是V层.在没有各其他框架发生关系的情况下.actionform就是V层.如查Struts加入了其他框架.像Spring,hibernate.actionform就是M层.所以针对不同的情况与应用.角色会发生变化,这是应用的需要,也是Struts的扩展性.
boyszz
发表文章: 15
注册时间: 2007年09月09日 04:22
悄悄话
个人博客
回复:re:关于Struts中MVC划分的疑问? 2007年09月09日 20:06
MVC架构只是针对你的WEB层设计,并不是你整个J2EE的架构.通常,你的一个项目是由WEB层(或者说是UI层,这样更通用一点)、业务层和持久层构成的。
ActionForm是什么?是用来对应你表单里的数据的,通常也会是一个领域对象,例如用户注册的一个表单Form,那这个表单数据最终会生成一个User这样的领域对象,并调用业务层UserService.addUser( User user )这样一个方法来进行保存用户数据,判断用户名是否重复,写进数据库这些操作都应该是addUser方法做的。所以他属于Modle,如果一个领域对象不需要通过继承ActionForm,就可以映射到一个表单,对我们开发来说那就更好了。至少。你不用写一个User,一个UserForm,两个并无区别的对象.这也是Struts设计上的一个失误.并受人指责.
回复:回复:re:关于Struts中MVC划分的疑问? 2007年09月10日 09:52
表现层框架 设计模式 struts mvc模式
看一个东西是什么层次,就必须想想这个东西是怎么来的,为什么会有这个东西。
那ActionForm来看,为什么Struts设计的时候会有这么个玩意儿?其实目的很简单,两个目的(其实是一个目的),第一,将你提交的数据自动转换成一个类,第二,将执行完业务逻辑的结果数据自动映射到你的jsp中。所以ActionForm目的是为了和jsp中的哪些标签做一个自动匹配的玩意。那结论就简单了,既然jsp是属于View的,那么ActionForm自然也是属于View的,因为如果你改变了jsp(当然不是修改简单的文本什么的),那么你的ActionForm也需要跟着改变。
在从另外一个角度来看,什么是Model,那是业务模型,什么情况下业务模型会变,当然是业务变化的时候,模型才会变化,模型怎么可能随着jsp的变化而变化呢。
那么为什么会有人会觉得ActionForm是Model呢,因为这样可以减少一个从Model到ActionForm的转换啊。但是假如现在我们要增加一个非浏览器的Client,同样使用这个业务逻辑,怎么办,也让这个Client使用ActionForm?
freebox
发表文章: 365
注册时间: 2008年03月01日 01:08
悄悄话
个人博客
re:关于Struts中MVC划分的疑问? 2008年05月28日 10:48
不必保证领域实体和formBean是两个类,只要保证它们是两个对象即可。在领域实体和form一致的时候可以不必要再做一个formBean类,只要生成一个formBean对象即可。当然在不一致的时候formBean类还是有价值的。
另一篇关于Struts的关于MVC的文章,这里转载过来供大家讨论:
版权所有:(xiaodaoxiaodao)蓝小刀 xiaodaoxiaodao@gmail.com
http://www.blogjava.net/xiaodaoxiaodao/archive/2007/03/26/106522.html
转载请注明来源/作者
struts 学习笔记之MVC模式
struts 中的MVC架构如下:
View :由JSP、Struts自定义标记库、资源文件(MessageResources.properties)共同组成,通过ActionForm实现JSP表单的封装,并映射到Model部分中JavaBean的相应属性中,完成用户数据的封装。
注意:关于ActionForm,有些人认为它属于Model层(仁者见仁,智者见智)。
事实上它不是Model,真正的Model应该是一个封装了业务逻辑的的对象。
而ActionForm仅仅是一个form-bean,封装了用户提交的表单数据(物理View),可以在其中进行一些非业务逻辑的验证,并没有真正的映射到模型数据,因为与层的关系比较密切,所以实际上它应该算是View层(逻辑View)。
Action 处理器对象可以直接对ActionForm进行读写,而不再需要和request、response对象进行数据交互。通过ActionForm组件对象实现了对View和Model之间交互的支持。M模型层,原则上来说和业务逻辑有关的东西都在这里处理。
Controller :接收客户端的request,进行业务逻辑处理,response到客户端。在Struts中Controller功能由图中ActionServlet和ActionMapping对象构成:核心是一个Servlet类型的对象ActionServlet(在struts-config.xml中配置),实际上是一个前端控制器(Front Controller)。ActionServlet根据ActionMapping对象的定义跳转到不同的Action,每个ActionMapping对象实现了一个request到Action对象之间的映射。
注 :Controller层负责流程的控制,在处理Model层与View层之间的交互的同时,又将两者分离开来,从而实现了MVC模式。Model层包含了应用的核心部分,业务逻辑和数据存取。View层负责应用的界面。
在上面的图中看到Action位于Controller层,但也有很多人把它归于Model层,实际上 Action 仅仅描述"做什么",与"如何做"(Model)关系不大,把它归于 Controller 层比较合适。
Model :一般Model层可以划分为三部分:公共入口,业务逻辑(Bussiness Logic),数据持久化(DAO+JavaBean)。
在Spring+Hibernate的架构中,M可以用 Spring (Bussiness Interface + Bussiness Implement)表示业务逻辑,Hibernate实现数据持久化。
附 :PO/POJO/BO/DTO/VO的区别
---------------------------------------------------------
PO :persistent object持久对象
1 .有时也被称为Data对象,对应数据库中的entity,可以简单认为一个PO对应数据库中的一条记录。
2 .在hibernate持久化框架中与insert/delet操作密切相关。
3 .PO中不应该包含任何对数据库的操作。
---------------------------------------------------------
POJO :plain ordinary java object 无规则简单java对象
一个中间对象,可以转化为PO、DTO、VO。
1 .POJO持久化之后==〉PO
(在运行期,由Hibernate中的cglib动态把POJO转换为PO,PO相对于POJO会增加一些用来管理数据库entity状态的属性和方法。PO对于programmer来说完全透明,由于是运行期生成PO,所以可以支持增量编译,增量调试。)
2 .POJO传输过程中==〉DTO
3 .POJO用作表示层==〉VO
PO 和VO都应该属于它。
----------------------------------------------------------
BO :business object 业务对象
封装业务逻辑为一个对象(可以包括多个PO,通常需要将BO转化成PO,才能进行数据的持久化,反之,从DB中得到的PO,需要转化成BO才能在业务层使用)。
关于BO主要有三种概念
1 、只包含业务对象的属性;
2 、只包含业务方法;
3 、两者都包含。
在实际使用中,认为哪一种概念正确并不重要,关键是实际应用中适合自己项目的需要。
----------------------------------------------------------
VO :value object值对象 / view object表现层对象
1 .主要对应页面显示(web页面/swt、swing界面)的数据对象。
2 .可以和表对应,也可以不,这根据业务的需要。
注 :在struts中,用ActionForm做VO,需要做一个转换,因为PO是面向对象的,而ActionForm是和view对应的,要将几个PO要显示的属性合成一个ActionForm,可以使用BeanUtils的copy方法。
----------------------------------------------------------
DTO (TO) :Data Transfer Object数据传输对象
1 .用在需要跨进程或远程传输时,它不应该包含业务逻辑。
2 .比如一张表有100个字段,那么对应的PO就有100个属性(大多数情况下,DTO 内的数据来自多个表)。但view层只需显示10个字段,没有必要把整个PO对象传递到client,这时我们就可以用只有这10个属性的DTO来传输数据到client,这样也不会暴露server端表结构。到达客户端以后,如果用这个对象来对应界面显示,那此时它的身份就转为VO。
----------------------------------------------------------
DAO :data access object数据访问对象
1 .主要用来封装对DB的访问(CRUD操作)。
2 .通过接收Business层的数据,把POJO持久化为PO。
Struts概览
- 视图
视图是用户看到并与之交互的界面。视图向用户显示相关的数据,并能接收用户的输入数据,但是它并不进行任何实际的业务处理。视图可以像模型查询业务状态,但不能改变模型。视图还能接受模型发出的数据更新事件,从而对用户界面进行同步更新。
Web工程中,视图就是一组JSP文件。在这些JSP文件中没有业务逻辑,也没有模型信息,只有标签。
此外,通常把Struts框架中的ActionForm Bean 也划分到视图模块中。ActionForm Bean 也是一种JavaBean,Struts框架把用户输入的表单数据保存在ActionForm Bean 中,把它传递给控制器,控制器可以对ActionForm Bean中的数据进行修改,JSP文件使用Struts标签读取修改后的ActionForm Bean的信息,重新设置HTML表单。
图7 ActionForm Bean 的作用
- 模型
模型是应用程序的主体部分。模型表示业务数据和业务逻辑。一个模型能为多个视图提供数据。由于同一个模型可以被多个视图重用,所以提高了应用的可重用性。大型应用中,业务逻辑通常由JavaBean或EJB组件来实现。
- 控制器
控制器接手用户的输入并调用模型和视图去完成用户的需求。当Web用户单击Web页面中的提交按钮来发送HTML表单时,控制器接收请求并调用相应的模型组件去处理请求,然后调用相应的视图来显示模型返回的数据。
Struts控制器由ActionServlet类和Action类来实现。ActionServlet类是Struts框架中的核心组件。ActionServlet继承了javax.servlet.http.HttpServlet类,它在MVC模型中扮演中央控制器的角色。ActionServlet主要负责接收HTTP请求信息,根据配置文件struts-config.xml的配置信息,把请求转发给适当的Action对象。如果该Action对象不存在,ActionServlet会先创建这个Acton对象。
Action类负责调用模型的方法,更新模型的状态,并帮助控制应用程序的流程。
- Struts的配置文件struts-config.xml
上面讲到一个用户请求是通过ActionServlet来处理和转发的。那么,ActionServlet如何决定把用户请求转发给哪个Action对象呢?在Struts中,这些配置信息都存储在特定的XML文件struts-config.xml中,在该配置文件中,每一个Acton的映射信息都通过一个<action>元素来配置。
这些配置信息在系统启动时被读入内存,供Struts在运行期间使用。在内存中,每一个<action>元素都对应一个org.apache.struts.action.ActionMapping类的实例。
Struts的工作流程
对于采用Struts框架的Web应用,在Web应用启动时就会加载并初始化ActionServlet,ActionServlet从struts-config.xml文件中读取配置信息,把它们存放到各种配置对象中,例如Action的映射信息存放在ActionMapping对象中。
当ActionServlet接收到一个客户请求时,将执行如下流程。
(1)检索和用户请求匹配的ActionMapping实例,如果不存在,就返回用户请求路径无效的信息
(2)如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中。
(3)根据配置信息决定是否需要表单验证。如果需要验证,就调用ActionForm的validate()方法。
(4)如果ActionForm的validate()方法返回null或返回一个不包含ActionMessage的ActionErrors对象,就表示表单验证成功。
(5)ActionServlet根据ActionMapping实例包含的映射信息决定将请求转发给哪个Action。如果相应的Action实例不存在,就先创建这个实例,然后调用Action的execute()方法。
(6)Action的execute()方法返回一个ActionForward对象,ActionServlet再把客户请求转发ActionForward对象指向的JSP组件。
(7)ActionForward对象指向的JSP组件动态生成网页,返回给客户。
对于以上流程(4)、如果ActionForm的validate()方法返回一个包含一个或多个ActionMessage的ActionErrors对象,就表示表单验证失败,此时ActionServlet将直接把请求转发给包含用户提交表单的JSP组件。在这种情况下,不会在创建Action对象并调用Action的execute()方法。
图8 Struts响应用户请求的工作流程
第一个实例:helloapp
1、创建视图组件
- 一个JSP文件,hello.jsp
- 一个ActionForm Bean:HelloForm Bean
hello.jsp
<%@ page language="java" pageEncoding="utf-8"%> <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %> <%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html:html lang="true"> <head> <html:base /> <title><bean:message key="hello.jsp.title"/></title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body bgcolor="white"> <h2><bean:message key="hello.jsp.page.heading"/></h2><p> <html:errors/><p> <logic:present name="personbean" scope="request"> <h2> <bean:message key="hello.jsp.page.hello"/> <bean:write name="personbean" property="userName"/>!<p> </h2> </logic:present> <html:form action="/HelloWorld.do" focus="userName"> <bean:message key="hello.jsp.prompt.person"/> <html:text property="userName" size="16" maxlength="16"></html:text><br> <html:submit property="submit" value="Submit"></html:submit> </html:form><br> <html:image page="/struts-power,gif" alt="Powered by Struts"></html:image> </body> </html:html>
2、创建消息资源文件
hello.jsp使用<bean:message>标签来输出文本内容。这些文本来自于Resource Bundle,每个Resource Bundle都对应一个或多个本地的消息资源文件,本例中的资源文件为application.properties,
#Application Resources for the "Hello" sample application #Application Resources that are specific to the hello.jsp file hello.jsp.title=Hello - A first Struts program hello.jsp.page.heading=Hello World! A first Struts application hello.jsp.prompt.person=Please enter a UserName to say hello to : hello.jsp.page.hello=Hello #Validation and error messages for HelloForm.java and HelloAction.java hello.dont.talk.to.monster=We don't want to say hello to Monster!!! hello.no.username.error=Please enter a <i>UserName</i> to say hello to!
3、创建ActionForm Bean
Struts框架中定义的ActionForm类是抽象的,必须在应用中创建它的子类,来放具体的HTML表单数据。
HelloForm.java
package hello; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; public final class HelloForm extends ActionForm { private String userName = null; public String getUserName() { return (this.userName); } public void setUserName(String userName) { this.userName = userName; } /** * Reset all properties to their default values. */ public void reset(ActionMapping mapping, HttpServletRequest request) { this.userName = null; } /** * Validate the properties posted in this request. If validation errors are * found, return an <code>ActionErrors</code> object containing the errors. * If no validation errors occur, return <code>null</code> or an empty * <code>ActionErrors</code> object. */ public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if ((userName == null) || (userName.length() < 1)) errors.add("username", new ActionMessage("hello.no.username.error")); return errors; } }
从以上代码可以看出,ActionForm Bean 实质上是一种JavaBean,不过它除了具有JavaBean的常规方法,还有两种特殊方法:
- validate(): 用于表单验证
- reset(): 把属性重新设置为默认值
4、数据验证
Struts框架中的数据验证分为两种类型:表单验证和业务逻辑验证
(1)表单验证,HelloForm中的validate()方法
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if ((userName == null) || (userName.length() < 1)) { errors.add("username", new ActionMessage("hello.no.username.error")); } return errors; }
当用户提交了HTML表单后,Struts框架将自动把表单数据组装到ActionForm Bean中。接下来Struts框架会自动调用ActionForm Bean的validate()方法进行表单验证。如果validate()方法返回的ActionErrors对象为null,或者不包含任何ActionMessage对象,就表示没有错误,数据验证通过。如果ActionErrors中包含ActionMessage对象,就表示发生了验证错误,Struts框架会把ActionErrors对象保存到request范围内,然后把请求转发到恰当的视图组件,视图组件通过<html:errors>标签把request范围内的ActionErrors对象中包含的错误消息显示出来,提示用户修改错误。
(2)业务逻辑验证,业务逻辑验证由Action负责处理。
5、创建控制器组件
控制器组件包括ActionServlet类和Action类。ActionServlet类是Struts框架自带的,它是整个Struts框架的控制枢纽。Struts框架提供了可扩展的Action类,它用来处理特定的HTTP请求。
HelloAction.java
package hello; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; import org.apache.struts.util.MessageResources; public final class HelloAction extends Action { /** * Process the specified HTTP request, and create the corresponding HTTP * response (or forward to another web component that will create it). * Return an <code>ActionForward</code> instance describing where and how * control should be forwarded, or <code>null</code> if the response has * already been completed. */ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // These "messages" come from the ApplicationResources.properties file MessageResources messages = getResources(request); /* * Validate the request parameters specified by the user * Note: Basic field validation done in HelloForm.java * Business logic validation done in HelloAction.java */ ActionMessages errors = new ActionMessages(); String userName = (String)((HelloForm) form).getUserName(); String badUserName = "Monster"; if (userName.equalsIgnoreCase(badUserName)) { errors.add("username", new ActionMessage("hello.dont.talk.to.monster", badUserName )); saveErrors(request, errors); return (new ActionForward(mapping.getInput())); } /* * Having received and validated the data submitted * from the View, we now update the model */ PersonBean pb = new PersonBean(); pb.setUserName(userName); pb.saveToPersistentStore(); /* * If there was a choice of View components that depended on the model * (or some other) status, we'd make the decision here as to which * to display. In this case, there is only one View component. * * We pass data to the View components by setting them as attributes * in the page, request, session or servlet context. In this case, the * most appropriate scoping is the "request" context since the data * will not be neaded after the View is generated. * * Constants.PERSON_KEY provides a key accessible by both the * Controller component (i.e. this class) and the View component * (i.e. the jsp file we forward to). */ request.setAttribute( Constants.PERSON_KEY, pb); // Remove the Form Bean - don't need to carry values forward request.removeAttribute(mapping.getAttribute()); // Forward control to the specified success URI return (mapping.findForward("SayHello")); } }
Action 的工作机制
所有的Action类都是org.apache.struts.action.Action的子类。Action子类应该覆盖父类的execute()方法。当ActionForm Bean被创建,并且表单验证通过后,Struts框架就会调用ActionForm类的execute()方法。
访问封装在MessageResources中的本地化文本
在本例中,Action类的execute()方法首先获得MessageResources对象:
MessageResources message = getResources(request);
在Action类中定义了getResources(HttpServletRequest request)方法,该方法返回当前默认的MessageResources对象,它封装了Resource Bundle中的文本内容。接下来Action类就可以通过MessageResources对象访问文本内容。例如,如果要读取消息key为“hello.jsp.title”对应的文本内容,可以调用MessageResources类的getMessage(String key)方法:
String title = messages.getMessage("hello.jsp.title");
业务逻辑验证
ActionMessages errors = new ActionMessages(); String userName = (String)((HelloForm) form).getUserName(); String badUserName = "Monster"; if (userName.equalsIgnoreCase(badUserName)) { errors.add("username", new ActionMessage("hello.dont.talk.to.monster", badUserName )); saveErrors(request, errors); return (new ActionForward(mapping.getInput())); }
6、访问模型组件
HelloAction类创建了一个模型组件PersonBean对象,并调用它的saveToPersistentStore()方法保存userName属性:
PersonBean pb = new PersonBean(); pb.setUserName(userName); pb.saveToPersistentStore();
7、向视图组件传递数据
Action类把数据存放在request或session范围内,以便向视图组件传递信息。
request.setAttribute( Constants.PERSON_KEY, pb); // Remove the Form Bean - don't need to carry values forward request.removeAttribute(mapping.getAttribute());
以上代码完成两件事:
- 把PersonBean对象保存在request范围内
- 从request范围内删除ActionForm Bean。由于后续的请求转发目标组件不再需要HelloForm Bean,所以可将它删除
8、把HTTP请求转发给合适的视图组件
// Forward control to the specified success URI return (mapping.findForward("SayHello"));
9、服务器端装载 hello.jsp 的流程
(1)<bean:message>标签从Resource Bundle 中读取文本, 把它输出到网页上。
(2)<html:form>标签在 request 范围中查找 HelloForm Bean。如果存在这样的实例,就把 HelloForm 对象中的 UserName 属性赋值给 HTML 表单的 userName 文本框。由于页面首次加载时还不存在 HelloForm 对象,所以忽略这项操作。
(3)把hello.jsp的视图呈现给客户
10、表单验证的流程
在hello.jsp网页上,不输入姓名,直接单击【Submit】按钮,会看到下图中的网页:
图9、表单验证失败的hello.jsp
当客户提交 HelloForm 表单时,请求路径为“、HelloWorld.do”;
<html:form action="/HelloWorld.do" focus="userName">
那么服务器端执行表单验证的流程如下:
(1)Servlet容器在web.xml文件中寻找<url-pattern>属性为“*.do”的<servlet-mapping>元素:
<servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
(2)Servlet容器依据以上<servlet-mapping>元素的<servlet-name>属性“action”,在web.xml文件中寻找匹配的<servlet>元素:
<servlet> <servlet-name>action</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> <load-on-startup>2</load-on-startup> </servlet>
(3)Servlet容器把请求转发给以上<servlet>元素指定的ActionServlet,ActionServlet依据用户请求路径“、HelloWorld.do”,在Struts配置文件中检索path属性为“、HelloWorld”的<action>元素:
<action path = "/HelloWorld" type = "hello.HelloAction" name = "HelloForm" scope = "request" validate = "true" input = "/hello.jsp"> <forward name="SayHello" path="/hello.jsp" /> </action>
更确切的说,ActionServlet此时检索的是ActionMapping对象,而不是直接访问Struts配置文件中的<action>元素。因为在ActionServlet初始化的时候,会加载Struts配置文件,把各种配置信息保存在相应的配置类的实例中,例如<action>元素的配置信息放在ActionMapping对象中。
(4)ActionServlet根据<action>元素的name属性,创建一个HelloForm对象,把客户提交的表单数据传给HelloForm对象,再把HelloForm对象保存在保存在<action>元素的scope属性指定的request范围内。
(5)由于<action>元素的validate属性为true,ActionServlet调用HelloForm对象的validate()方法执行表单验证:
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if ((userName == null) || (userName.length() < 1)) errors.add("username", new ActionMessage("hello.no.username.error")); return errors; }
(6)HelloForm对象的validate()方法返回一个ActionErrors对象,里面包含一个ActionMessage对象,这个ActionMessage对象封装了错误信息,消息key为“hello.no.username.error”,在Resource Bundle中与之匹配的消息文本为:
Please enter a <i>UserName</i> to say hello to!
(7)ActionServlet把HelloForm的validate()方法返回的ActionErrors对象保存在request范围内,然后根据<action>元素的input属性,把客户请求转发给hello.jsp。
(8)hello.jsp 的 <html:errors> 标签从 request 范围内读取 ActionErrors 对象, 再从ActionErrors 对象中读取 ActionMessage 对象, 把它包含的错误消息显示在网页上。
11、逻辑验证失败的流程
(1)重复上面(1)~(4)
(2)ActionServlet调用HelloForm对象的validate()方法,这次validate()方法返回的ActionErrors对象中不包含任何ActionMessage对象,表示表单验证成功。
(3)ActionServlet查找HelloAction实例是否存在,如果不存在就创建一个实例。然后调用HelloAction 的 execute() 方法。
(4)HelloAction 的 execute()方法先进行逻辑验证,由于没有通过逻辑验证,就创建一个 ActionMessage 对象,这个ActionMessages errors = new ActionMessages();
execute()方法把 ActionMessage 对象保存在 ActionMessages 对象中,再把ActionMessage对象存放在request范围内。最后返回一个 ActionForward 对象, 该对象包含的请求转发路径为<action>元素的input属性指定的hello.jsp。
String userName = (String)((HelloForm) form).getUserName(); String badUserName = "Monster"; if (userName.equalsIgnoreCase(badUserName)) { /* * 创建错误信息 —— new ActionMessage("hello.dont.talk.to.monster", badUserName )), * 将 ActionMessage 对象保存到 ActionMessages 对象中。 * 接下来调用在 Action 基类中定义的 saveErrors() 方法,它负责把 ActionMessages 对象保存到 request 范围内。 * 最后返回 ActionForward 对象,该对象包含的请求转发路径为<action>元素的 input 属性指定的 hello.jsp —— new ActionForward(mapping.getInput()); */ errors.add("username", new ActionMessage("hello.dont.talk.to.monster", badUserName )); saveErrors(request, errors); return (new ActionForward(mapping.getInput())); }
有时候业务逻辑验证会对数据进行更为复杂的验证。在很多情况下,需要模型组件的介入,才能完成业务逻辑验证。
(5) ActionServlet 依据 HelloAction 返回的 ActionForward 对象, 再把请求转发给 hello.jsp
(6)hello.jsp 的 <html:errors> 标签从 request 范围内读取 ActionMessages 对象, 再从 ActionMessages 对象中读取 ActionMessage 对象, 把它包含的错误消息显示在网页上。
12、验证成功的流程
(1) 重复 (1)~(3)
(2)HelloAction 的 execute() 方法先执行逻辑验证, 这次通过了验证,执行相关的业务逻辑,最后调用 ActionMapping.findForward() 方法,
return (mapping.findForward("SayHello"));
(3)ActionMapping.findForward() 方法从 <action> 元素中寻找 name属性为 “SayHello” 的 <forward> 子元素,然后返回与之对应的 ActionForward 对象, 它代表的请求转发路径为 “/hello.jsp” 。
更确切地说,ActionMapping 从本身包含的 HashMap 中查找 name 属性为 “SayHello” 的ActionForward对象。在ActionServlet 初始化时会加载Struts配置文件,把<action>元素的配置信息存放在ActionMapping对象中,<action>元素中可以包含多个<forward>子元素,每个 <forward> 子元素的配置信息存放在一个 ActionForward 对象中, 这些 ActionForward 对象存放在 ActionMapping 对象的 HashMap 中。
(4)HelloAction 的 execute() 方法然后把 ActionForward 对象返回给 ActionServlet, ActionServlet 再把客户请求转发给 hello.jsp
发表评论
-
Altova UModel 2011r2 + SN
2011-06-17 12:45 4793User:lenovoCompany:lenovoKey-Co ... -
最新小说
2011-01-14 11:19 1112收录畅销小说的最新章节 最新小说网 -
Struts1.2 介绍(3)
2009-08-13 17:28 0配置多应用模块 Struts 1.x 支持多应用 ... -
Struts1.2
2009-08-10 17:39 01. Introduction "Read ... -
Struts1.2 介绍(2)
2009-08-06 13:13 2971为Struts应用配置 web.xml 文件 (1) ... -
利用ActionMapping的命令模式
2009-08-03 17:49 0Struts提供一个公开的基于XML语句的方法来说明请求 ... -
Struts的工作流程
2009-07-30 15:39 1260对于采用Struts框架的Web应用,在Web应用启动 ... -
Tiles
2009-01-29 14:05 0http://203.208.33.101/search?q= ... -
DispatchAction类的使用
2008-07-20 01:44 1744一. 由来 最近用St ... -
ActionForm的生命周期浅探
2008-07-20 01:40 1482看了很多的资料书籍,都提了一下ActionForm的生 ...
相关推荐
Struts1.2驱动包是Java Web开发中一个重要的组件,它是Apache Struts框架的特定版本,用于支持基于Model-View-Controller (MVC)设计模式的应用程序开发。Struts1.2因其稳定性和广泛的功能集而在过去备受推崇,尤其在...
Struts1.2是Apache软件基金会的开源框架,主要用于构建基于Java的企业级Web应用程序。它遵循Model-View-Controller(MVC)设计模式,提供了一种结构化的方式来组织应用程序,从而提高了开发效率和代码可维护性。这次...
Struts1.2、Spring2.5和Hibernate3.2是经典的Java企业级开发框架组合,它们各自在应用程序的不同层次上发挥着重要作用。Struts1.2是一个MVC(Model-View-Controller)框架,主要负责处理用户界面与业务逻辑之间的...
首先,手册会介绍Struts1.2的核心概念,包括Action类、Form Bean和Tiles布局。Action类是处理用户请求的核心,它接收来自控制器的请求并执行相应的业务逻辑。Form Bean则用于在控制器和视图之间传递数据,通常包含...
1. `lib`目录:包含各种依赖的JAR文件,如Struts的核心库、Servlet API、JSP API等,这些都是构建基于Struts1.2的应用程序所必需的。 2. `docs`目录:文档资料,包括API参考、用户指南等,帮助开发者理解Struts1.2的...
1. **ActionServlet**:Struts1.2使用单一的ActionServlet处理所有请求,而Struts2引入了Front Controller模式,所有的请求都由StrutsPrepareAndExecuteFilter处理。 2. **表达式语言**:Struts2使用OGNL(Object-...
Struts1.2是Apache软件基金会的Jakarta项目下的一个开源框架,主要用于构建基于Java的Web应用程序。这个框架的核心是Model-View-Controller(MVC)设计模式,它提供了一种结构化的、可扩展的方式来组织和管理应用的...
Struts1.2是一款历史悠久且广泛使用的Java Web框架,它基于Model-View-Controller(MVC)设计模式,为开发人员提供了构建动态、数据驱动的Web应用的强大工具。该框架在2004年首次发布,是Apache软件基金会的一个项目...
Struts1.2框架是Apache组织开发的一个基于MVC(Model-View-Controller)设计模式的Java Web应用程序框架。在Struts1.2中处理表单提交,特别是当表单数据包含列表对象时,需要理解一些核心概念和技术。这篇博客文章...
Struts1.2标签是Java Web开发中Struts框架的一部分,它提供了一种在JSP页面中更加便捷、可维护的方式来处理业务逻辑和控制流程。Struts1.2标签库大大简化了视图层的开发,使开发者可以避免过多地在JSP中编写Java脚本...
Struts 1.2驱动包是Apache软件基金会开发的一个基于MVC(Model-View-Controller)设计模式的Java Web应用程序框架。它旨在提供一个结构化的、可扩展的平台,帮助开发者构建更易于维护和管理的Web应用。Struts 1.2...
Struts 1.2 是一个历史悠久的Java Web框架,由Apache软件基金会开发,它在Web应用开发领域曾经占据了重要的地位。这个压缩包包含了Struts 1.2版本的类库和源码,使得开发者能够方便地研究和学习这个经典框架的工作...
Struts1.2是Apache软件基金会的一个开源框架,主要用于构建基于Java的企业级Web应用程序。它遵循Model-View-Controller(MVC)设计模式,提供了一种结构化的方式来组织应用程序的业务逻辑、用户界面和控制流程。这个...
Struts 1.2 是一个基于MVC(Model-View-Controller)设计模式的Java Web应用程序框架,由Apache软件基金会开发。它极大地简化了构建动态、数据驱动的Web应用的过程,提高了开发效率和代码的可维护性。这个压缩包文件...
1. **配置Struts1.2**: 在开始文件上传之前,我们需要在Struts的配置文件`struts-config.xml`中进行相应的配置。这包括声明一个Action,该Action将处理文件上传的请求。你需要定义一个`<action>`标签,指定Action...
1. **MVC模式**:Struts1.2遵循MVC设计模式,将应用程序的业务逻辑、视图呈现和用户交互分离开来,使得代码更加模块化,易于维护和测试。模型层处理数据,视图层负责展示,而控制器则协调这两者之间的交互。 2. **...
Struts1.2是一个经典的Java Web开发框架,它在早期的Web应用开发中扮演了重要角色,尤其是在MVC(Model-View-Controller)设计模式的实现上。本项目"基于Struts1.2的上传下载Demo"是针对该框架的一个实践示例,旨在...
本文将详细介绍Struts1.2中的拦截器使用以及相关的插件。 首先,我们需要理解拦截器的工作原理。拦截器在Action调用前后执行,形成一个拦截链。当一个请求到达时,Struts框架会按照配置的顺序依次调用这些拦截器,...
Struts1.2是Apache软件基金会的一个开源项目,它是一个基于MVC(Model-View-Controller)设计模式的Java Web应用程序框架。这个框架的主要目的是为了简化Web应用开发,提高开发效率,提供一套标准的方式来处理HTTP...