struts 1 介绍
Posted 余同学的开发之路
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了struts 1 介绍相关的知识,希望对你有一定的参考价值。
关于框架:是一种长期经验总结出来的一种优化开发的方案,用于提高开发效率,节省财力。
使用 struts 1 开发步骤
1.搭建环境:
1) 导入jar包(可以从官网下载的例子中找到所需的jar包)
2) 建立一个配置文件 struts-config.xml 放在 WEB-INF 下
3) 在 web.xml 中,配置前端控制器 ActionServlet 。在服务一启动就实例化,故配置 load-on-strartup 为 0 。并引入 struts-config.xml 文件 。
2.建立 ActionForm(用于封装页面 Form 表单提交的参数)
关于ActionForm:
An ActionForm is a JavaBean optionally associated with one or more ActionMappings. Such a bean will have had its properties initialized from the corresponding request parameters before the corresponding Action.execute method is called.
ActionForm 是一个 JavaBean,它可以与一个或多个 Action 映射相关联 。这样的 bean 将从相应的请求参数中初始化其属性 。在相应的 execute 方法被调用之前执行 。
1) 创建一个类,继承 ActionForm
2) 在 struts 配置文件中注册该 Form
<form-bean name = "" type = ""><form-bean/>
3.建立 Action
1) 建立一个具体的 Action 类,继承 Action 类
2) 在 struts 配置文件中配置该类
<action path ="" type = "" name = "">
<forword name = "" path = ""></forword>
</action>
4.创建页面
struts 1 的执行流程概述
1.浏览器发送请求 login.do 由服务器根据 web.xml 文件来判断是否把该请求传递给前端控制器 。
2.请求进入前段控制器之后就没有 .do 了,ActionServlet (前端控制器)会把 url 和配置文件中 action 标签的 path 属性作比较。
3.若不存在与之对应的 path ,则报错 no action config found for
the specified url 。
4.若存在,则会把请求传递到后端控制器,也就是具体的 Action 的子类去处理请求,并带上与之对应的 form 表单 。
5.后台控制器用于处理逻辑,调用其它的业务模块。执行之后会返回一个目标相应对象中的关键字给前段控制器。
6.前段控制器查到配置文件找到对应的关键字所对应的 jsp 页面,或者是另一个 Action 调转。
struts 1 执行的具体流程分析
1.读取配置:总控制器 ActionServlet 是一个 Servlet 在 web.xml 中配置成自动启动的 Servlet 为不同的 struts 模块初始化相应的 ModuleConfig对象,如:ActionConfig ControlConfig FormBeanConfig ForwordConfig MessageRresourceConfig 所以 struts 需要使用 xml 解析技术 。
2.发送请求 :用户提交表单或调用 URL 使用 HTTP 协议上传给 Web 服务器 。
3.填充 Form(实例化 复位 填充数据 校验 保存)
(.do请求)从 ActionConfig 中找到对应该请求的 Action 的子类,且这个 Action 有一个对应的 ActionForm 。ActionForm 被实例化并用 HTTP 请求的数据填充其属性,并且保存在 ServletContext 中(request或session中)这样他们就可以被其他 Action 对象或者 JSP 调用 。
4.派发请求:控制器把请求转发到一个具体的 Acton,相应的 FormBean 一并传给 Action 的 execute()方法,根据配置文件的 action 标签的 path 属性和 type 属性找到具体的 Action。此时配置文件已经在内存中了 。
一启动服务器就会读取 web.xml 此时加载核心控制器,进而读取配置文件 。
5.处理业务:Action 一般只包含一个 execute 方法,它负责执行相应的业务逻辑(调用其他业务模块)完毕后返回一个 ActionForword 对象,控制器通过该 ActionForword 对象来进行转发工作。ActionForword 代表一个跳转目的地,可以根据 ActionMapping 中配置的路径跳转,也可以是自定义的路径 。
6.Action 根据业务处理的不同结果返回一个目标响应,该响应不是一个具体的 jsp 页面,而是一个关键字,对应着一个具体的 jsp 页面或是另一个 Action 。
7.查找响应:总控制器根据返回的关键字,找到对应的资源对象 。
8.响应用户:目标响应对象(jsp)将结果(jsp 在服务器解析之后就是一堆 html 和 js 代码发送给浏览器,浏览器解析即可展现给用户 )展现给用户 。
模块的详细介绍
ActionServlet 的详细介绍:
在 web.xml 中配置
包含初始化参数 config 缺省值 可以不配
但是初始化的参数名就那几个,也不能随便写
Action 的详细介绍:
Action 是用户 URL 和业务逻辑的适配器
url 的的传递一共有两次,第一是服务器发送给 ActionServlet
第二是 ActionServlet 发送给 Action
Action 什么时候创建的?
用户发送请求的时候创建,且只创建一次。
所有的请求都使用这一个 Action 实例 。所以就有了线程安全问题 。
怎么解决线程安全问题呢?
不要用实例变量存储只是针对某个请求的数据。注意资源操作,存储的同步性。
1.同步机制
2.使用 ThreadLocal
ActionMapping 的详细介绍 :
继承 ActionConfig 类
ActionMapping 对象就是对 Action 标签内部的配置信息的封装。
其中有 getPath() getType() getName() 等方法用于获取标签内部的信息 getName() 是获取 form-bean 的 name 。 getAttribute() 获取的才是用于指向 form 表单的 key 值 。
ActionMapping 的主要功能就是管理 Action 的信息和管理 Action 执行完成以后的 ActionForward 的信息 。
ActionForword (导航器):代表控制器调转的目的地
redirect:设置为 true 则为重定向,默认是 false 为 forword 转发。
ActionForm 的详细介绍:填充 Form
要用 Form 首先根据请求 RUL 去配置文件找到 Action 然后根据action 标签的 name 属性值找到对应的 form-bean 。
检查 Action 的 form-bean 的使用范围(request session),确定使用范围下是否已经存在 ActionForm 的实例,没有则创建并存在相应的域中。
注意:在这里涉及到一种思想,就是拿来一个变量 上来就判断是不是空,不是空、则直接使用,为空则先创建然后再使用,然后从页面获取参数,用 setter 方法赋值(静态表单使用这种方法,动态表单则使用 map 存放) 若设置校验就进行校验 调用 validate 方法 。
如果是静态的 From,则是通过上面的方法,即用 setter 方法为 form 赋值,而 DynaActionForm 把所有的属性保存在一个 Map 对象中,因此访问 DyanActionForm 中的属性与访问 Map 对象中的方法类似 map.getString() 或 map.get() 。
form 填充的执行顺序:
ActionServlet 为 form 填充数据
首先创建一个实例,并添加到相应的域中
调用 reset() 方法 执行复位操作 目的:若 Form 设置为在 session中,则会有多个 request 进行调用所以在每个请求调用之前,需要恢复初始化值。这也从侧面证实了一个 Action 只能有一个 form 与之对应,而一个 form 可以对应多个 Action ,就是放在 session 域中的 form 。
调用相应的setter方法
调用校验方法(默认是校验)
ActionForm 注意事项:
无参构造方法必须有,因为要在 ActionServlet 中使用反射为表单赋值。
如何分析 ActionForm 的执行效果:
1.从过程上去查看,使用监听器:HttpSessionAttributeListener,ServletRequestAttributeListener 可以判断是否有属性的变化 。
2.从结果上去看,在各自的 set 方法内部添加输出语句即可 。会打印出来 。
思考:
1.谁来填充 Form?什么时候填充?根据什么来填充?
ActionServlet 来填充 在请求进来之后填充 根据传递过来的 url 中携带的参数来填充 。
2.ActionServlet 怎样把请求派发给 Action?
ActionMapping 封装了配置信息,通过它可以找到 path 进一步可以对应上具体的 Action 。
3 Action 怎么跳转?
借助 ActionForword (继承 ForwordConfig)可以读取到配置文件中 forword 标签的信息 。
action 标签的属性分析:
name:与表单的 name 一样 。
type:该 action 的全类名 。
path:访问该 Action 的 URL 。
scope:用于控制 form 的填充范围 默认 session 。
validate:用于控制是否校验 action 所引用的表单 默认校验 。
attribute:用于存储 form 表单的 map 所对应的 key,缺省值与name 一样,而 name 和表单一样,所以看起来就好像是 name 指定了 action 绑定的表单一样 。
input:在 validate 为 true 的前提下,如果表单检验出错,则调转到 input 属性指定的页面,路径为相对路径 。
eg:用户登录
项目结构:
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>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
struts.xml
<struts-config>
<form-beans>
<form-bean name="loginForm" type="yu.LoginForm"></form-bean>
</form-beans>
<action-mappings>
<action path="/login" type="yu.LoginAction" name="loginForm">
<forward name="success" path="/success.jsp"></forward>
<forward name="fail" path="/fail.jsp"></forward>
</action>
</action-mappings>
</struts-config>
login.jsp
<form action="login.do">
用户名:<input type="text" name = "username"/><br>
密码:<input type="text" name = "password"/><br>
<input type="submit" value = "submit"/>
</form>
LoginAction.java
public class LoginAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
LoginForm login = (LoginForm) form;
if (login.getUsername().equals("admin")) {
return mapping.findForward("success");
} else {
return mapping.findForward("fail");
}
}
}
LoginForm.java
public class LoginForm extends ActionForm {
private static final long serialVersionUID = 1L;
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
以上是关于struts 1 介绍的主要内容,如果未能解决你的问题,请参考以下文章