1.为什么要使用Struts框架
1.1 建立在MVC这种公认的好的模式上的
1.2 开源项目
1.3 可以与其他技术和框架具有很好的额融合性。如:Spring
1.4 可以减少重复代码的开发,提高工作效率
2. FrameWork的概念
人们用于解决相同问题或者相似问题的方案。
特点: 可重用性、可扩展性、可收缩性
控制器、业务逻辑层、数据逻辑层。
3. Struts的概念和体系结构
Struts是Apache组织的一个开源项目,主要是采用Servlet和JSP技术来实现的。
Struts是一个基于Sun Java EE平台的MVC框架,它采用MVC模式,将MVC模式分层显示逻辑和业务逻辑的能力发挥的淋漓尽致。
4. Struts实践步奏
4.1 搭建环境
l 导入jar包 :使用其中相关的类
l 建立一个配置文件:struts-config.xml. 一般放置在WEB-INF下
l web.xml文件 :注册Struts中心控制器ActionServlet
<?xml version="1.0" encoding="UTF-8"?> |
<?xml version="1.0" encoding="UTF-8"?> |
4.2 建立ActionForm
l 建立一个类继承ActionForm
l 注册ActionForm,通知Struts
4.3 建立Action
l 建立一个类继承Action并实现execute方法
l 注册Action
4.4 页面访问
- 读取配置(初始化ModuleConfig对象)
Struts框架总控制器(ActionServlet)是一个Servlet,在web.xml中配置成自动启动的Servlet。读取配置文件(struts-config.xml)的配置信息为不同的struts模块初始化相应的ModuleConfig对象: ActionConfig,ControlConfig, FormBeanConfig,ForwardConfig
2. 发送请求
用户提交表单像Web应用程序提交一个请求,请求的数据用Http协议上传给Web服务器。(如果是*.do的请求才能传给struts框架)。
3. 填充Form(实例化、复位、填充数据、校验、保存)
(*.do)从ActionConfig中找出对应请求的Action子类,如果没有对应的Action,控制器直接转发给JSP或静态页面。如果对应的Action且这个Action有一个对应的ActionForm,ActionForm被实例化并用Http请求的数据填充其属性,并且保存在Servlet Context中,这样他们就可以被其它Action对象或者JSP调用。
4. 派发请求
控制器根据配置信息ActionConfig将请求派发到具体的Action,相应的FormBean一并传给这个Action的execute()方法。
5. 处理业务
Action一般只包含一个execute方法,他负责执行相应的业务逻辑(调用其它业务逻辑)。完毕返回一个ActionForward对象,控制器通过该ActionForward对象来进行转发工作。
6. 返回响应
Action根据业务处理的不同结果返回一个目标相应对象给总控制器,该目标相应对象对应一个具体的JSP页面或另外一个Action。(返回的并不是具体的JSP页面,而是和JSP页面相对应的关键字)
7. 查找响应
总控制器根据业务功能Action返回的目标响应对象,找到对应的资源对象,通常是一个具体的JSP页面。
8. 响应用户
目标相应对象将结果展现给用户目标响应对象(JSP)将结果页面展现给用户。
Struts四剑客:ActionServlet,Action,ActionForm和配置文件。
Struts中的MVC:
- Model:本质上来说在Struts中的Model是一个商业逻辑类,开发者实现商业逻辑。
- 控制器:前端控制器是一个Servlet,它将客户端请求转发到相应的后端控制器。
- View
ActionServlet(中心控制器)
定义:它提供一个中心位置来处理全部的终端请求。
作用:接受请求,填充数据,派发请求,响应用户。
配置:在web.xml文件中声明。
<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> <!-- 为了让servlet一启动就实例化--> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> |
第一次请求由web容器接收,将*.do的请求转发给Struts的中心控制器。再由中心控制器派发给对应的Action。 |
Action:
l Action是在第一次请求时被初始化,不是在读取配置文件时初始化。每个Action之会初始化一次。
l Action不是线程安全的,因为所有的请求共享一个Action实例。。
解决办法:
a.注意不要用实例变量或者类变量共享只是针对某个请求的数据
b.注意资源操作的同步性。
ActionMapping:
每一个<action>元素都与ActionMapping类的一个实例相对应。包括name,path,forwards.
ActionForward:
ActionForward对象封装了先前进的URL路径且被请求处理器用于识别目标试图。
redirect属性:true容器外跳转,path写绝对路径,要加上协议。 RequestDispatcher.forward
false 路径相对当前应用。 HttpServletResponse.sendRedirect
ActionForm:
处理ActionForm的工作原理:
l 检查Action的映射,确定Action中已经配置了对ActionForm的映射。
l 根据name属性,查找form bean的配置信息。
l 检查Action的form bean的使用范围,确定在此范围下(request,session),是否已经有此form bean的实例。
l 假如当前范围下,已经存在了此form bean的实例,而且对当前请求来说,是同一类型的话,那么就重用。
l 否则,就重新构建一个form bean的实例(调用构造方法),并且保存在一定作用范围。
l form bean的reset()方法被调用。
l 调用对相应的setter方法,对状态属性赋值。(取值(从客户端参数request.getParameter))
l 如果validate的属性设置为true,那么就调用form bean的validate()方法。
l 如果validate()方法没有返回任何错误,控制器将ActionForm作为参数,传给Action实例的execute()方法并执行。
注意:直接从ActionForm类继承的reset()和validate()方法,并不能实现什么处理功能,所以有必要自己重新覆盖。
1. 无参构造方法必须有 2. Scope缺省值是session 3. 表单中的name属性与Form中的set方法匹配并不是和属性名字
思考:ActionForm如何被存储?如何确定是否调用了scope.setAttribute(name,form)?
方法一:从过程看:监听来分析。 监听分为:对象的监听和对象属性的监听(监听为什么没有url,因为它是针对事件的)
方法二:从结果看:从execute方法中查看。 scope.getAttibute(),名字参考配置文件的name属性
validate校验:如何判断框架是否调用valiate()方法?实现此方法,并打印出。
常见属性:validate:控制是否进行校验表单(校验开关)
attribute:用来存取form的关键字,缺省值与name一样。
global-forwards
Struts实现思路:
开发以下类: 1. ActionServlet : 读取配置、填充form、 派发请求(调用对应action的execute方法)、查找相应
2. ActionForm: reset 、 validate
3. Action:execute()
4. ActionMapping:属性:path name type validate forwards 5. ActionForward: name path 6. 配置文件
模仿填充form: