struts2执行的基本过程
1.浏览器发送请求
2.过滤器拦截
获取到请求路径
得到路径的内容
到src下找struts.xml,使用dom4j解析,匹配action标签
匹配name属性的action标签的class值,通过反射来实现---------->反射是框架的灵魂
得到action方法的返回值,匹配struts.xml里action标签里有result标签,匹配result属性,如果一样,跳转到配置页面
struts的分模块开发
1.单独写配置文件
2.引入配置文件到struts.xml中
重定向和转发的区别
1.重定向:服务器内部进行的操作,可以携带数据,一次请求
2.转发:浏览器端进行的操作,二次请求
struts2中配置常量的三种方式
1.在struts.xml中
2.在struts.properties中
3.在web.xml中
action的三种编写方式
1.普通类
2.实现action接口
3.继承actionSupport类(常用)
访问action的方法
三种实现方式
1.使用action标签的method属性
缺点:每个方法都需要配置,方法很多的时候,需要配置很多的action
2.通配符(重点)
name属性写*,method属性写{1}获取*的值
3.动态访问实现(不用)
错误注意
1.如果action有返回值,在配置文件没有配置,出现错误
2.在action里面的方法有返回值,返回值类型必须为String
3.可以没有返回值,result标签不需要配置
(1)返回值写void
(2)返回值写none(类似于null)
全局结果页面:多个action的返回页面一样,作用在当前的package
全局和局部都配置时,采用局部的配置
action标签的result标签
type属性:如何到路径(转发还是重定向)
默认是转发dispather,一次请求
重定向是redirect,两次请求
上面两个一般针对到页面中的配置,
配置到其他action
chain:转发,一般不用,缓存问题
redirectAction:重定向到action
获取表单数据的方式
1.ActionContext
2.SercletActionContext
3.接口(不常用)
值栈
在action中操作域对象,存数据(原始action,struts2提供了更便捷的值栈来进行存取值)
1.原生方式:获取request对象
2.属性封装:定义成员变量,生成set(和get方法),变量名和表单输入项的name属性值一样(底层:根据name属性匹配,然后调用set方法)
3.模型驱动封装:封装到实体类
action实现ModelDriven(泛型写实体类)
实现接口的方法,返回实体类对象
在action里创建实体类对象
注意:属性封装和模型驱动封装不能同时使用,同时使用时属性封装失效
4.表达式封装(也可以归于模型驱动封装)
声明实体类
生成set和get方法
在表单里写表达式(如user.username)(底层:先用user找实体类,调用get方法,然后用set方法赋值)
表达式封装和模型驱动封装不同点
1.模型驱动封装只能把数据封装到一个实体类对象中
2.表达式可以封装到不同的实体类
封装到list list[索引].username
封装到map map[键].username
1.声明list,map,泛型是实体类
2.生成setget方法
EL表达式:只能用在jsp中,用于获取域对象中的值
OGNL表达式:在struts里和struts2标签一起使用操作值栈
OGNL不是struts2的一部分,是单独的项目,经常和struts一起使用
1.导入jar包
2.在jsp页面中引入struts2的标签库
3.使用struts2标签进行操作 <s:property value="'haha',length()">(重点,常用) value用来获取action值栈中的值
值栈:
web阶段:在servlet里把数据放在域对象中,在页面中用EL表达式获取数据,域对象在一定范围内,存值和取值
action阶段:struts2提供的一种存储机制类似于域对象,是值栈,可以存值和取值,在action中把数据放到值栈里,在页面获取值栈数据
servlet和action区别
1.Servlet:默认第一次访问的时候创建,只创建一次,单实例对象
2.Action:访问时候创建,每次访问都会创建action对象,创建多次,多实例对象
值栈存储位置:
每次访问action,都会创建action对象,每个action对象里都会有一个值栈对象(只有一个)
获取值栈对象 (栈:先进后出[压栈弹栈])
1.常用方式:ActionContext对象的getValueStack()方法
值栈的内部结构(主要是root和context)
root 结构是list集合(常用) 类继承ArrayList
context 结构是map集合 类继承Object实现Map
context存储的是对象引用
key(固定) value
request request对象引用
seccion Httpseccion对象引用
applilcation ServletContext对象引用
parameters 传递相关的参数
attr 三个域对象,往三个域对象放值,名称都相同时,使用arr操作,获取范围最小的域对象放的值
访问action(创建action[值栈])-->返回值返回到页面-->页面取值
<s:debug>可以在页面进行debug,查看值栈对象
action中有值栈对象,值栈中有action对象的引用
向值栈放数据
1.调用值栈的set方法 root(list)里面会压栈一个map
2.获取值栈对象里的push方法 root(list)里面会压栈一个String
3.在action中定义成员变量,生成get方法,在执行的方法中直接引用,数据直接放在root里的action对象中,不会再有栈压进来,节省空间
向值栈中放字符串
向值栈中放对象
1.定义私有成员变量(直接new出来或者在执行的方法中new出来)
2.生成get方法
3.在执行的方法中向值栈中放数据
向值栈中放list集合
1.定义list集合变量
2.生成变量的get方法
3.在执行的方法里面向list集合设置值
页面从值栈中获取数据(使用struts2的标签和OGNL表达式)
获取字符串 根据名称获取值(会去到action中找到get方法,获取值)
获取对象 根据对象名.属性名
获取list 1.list[索引].属性名
2.<s:iterator value="list">遍历值栈中的list集合
<s: property value="直接写对象的属性名">
</s:iterator>
3.(便利list集合,得到每个user对象,机制-->每次把遍历出来的对象放到context里的临时变量里)
(获取context里面数据特点-->写OGNL表达式-->使用符号#)
(好处:提升效率)
<s:iterator value="lilst" var="对象">
<s: property value="#对象名.属性名">
</s:iterator>
set方法放入的取值-->根据名称取值
push方法放入的取值-->会把数据存到值栈中的数组里,数据名为top,根据数组获取值 <s:property value="[0].top"/>获取数据中的值
使用foreach标签和EL表达式获取list的数据(性能低)
<c:foreach item="${list}" var="对象名">
${对象名.属性名}
</c:foreach>
EL表达式为什么可以获取值栈数据?
底层增强request域获取值,如果获取到,直接返回.
如果获取不到,到值栈中把值获取出来,放到域对象中
OGNL中的#用来获取context中的值
<s:property value="#域对象.key名">
OGNL中的%
在struts2的标签中使用OGNL表达式需要用%{OGNL表达式}
struts2拦截器
1.struts2里面封装了很多功能,有很多拦截器,但是不是每次这些拦截器都执行.默认拦截器每次都执行
拦截器在什么时候执行?(重点)
1.在action对象创建之后,action的方法执行之前
拦截器底层原理
1.aop思想--->面向切面(方面)编程
有基本功能,在不通过修改源代码的方式来扩展功能
2.责任链模式 (和过滤链模式很相似)
过滤链模式--->一个请求可有多个过滤器,每个过滤器只有做放行才能到下一个过滤器
责任链模式--->多个拦截器依次放行
aop思想和责任链模式如何应用到拦截器里面???
1.在action方法执行之前执行拦截器,执行过程使用aop思想,在action没有直接调用拦截器的方法,使用配置文件方式进行操作
2.在执行拦截器的时候,使用责任链模式
源代码解析
1.执行action
2.创建action对象(使用动态代理)
3.执行action的拦截器方法
4.执行很多的拦截器,遍历执行
5.类似于放行操作的方法
6.执行action的方法
过滤器和拦截器的区别
过滤器:dispather前端控制器,在servlet外部
过滤器理论上可以过滤任意内容,比如html,jsp,servlet,图片路径.
拦截器: 可以拦截action
自定义拦截器—>场景—>struts2框架里面的拦截器没有我们要使用的功能
拦截器结构
1.类继承AbstractInterceptor类
2.AbstractInterceptor类实现Interceptor接口
3.接口里有3个方法
init() 初始化操作
destroy() 销毁
intercept() 拦截逻辑操作
开发中建议--->1.写类,让类继承MethodFilterInterceptor类
2.让action里面的某个方法不进行拦截
通过配置文件让action和拦截器建立关系
自定义登录拦截器
1.写类,让类继承MethodFilterInterceptor类,重写类里面的方法doIntercept();
放行方法invocation.invoke()
不放行,可以用返回值配置到页面
2.配置action和拦截器的关系(注册拦截器)
1.在要拦截的action标签所在的package标签里声明拦截器<interceptor name class>
2.在具体的action标签引入拦截器
3.在struts2有很多默认拦截器,如果配置了自定义的,默认的就不会执行了,所以要引入默认拦截器的整个包defaultStack
4.配置拦截器,对action里的所有方法都进行拦截,但是login方法不能进行拦截,所以要配置不拦截
5.在使用拦截器里面配置不拦截方法的名称<param name="excludeMethods">方法名</param>
6.再次登录后会出现套页面现象--->解决--->form表单上加target属性 target="_parent" 设置打开位置
struts2标签使用jsp页面中
1 s:property: 和ognl表达式在jsp页面中获取值栈数据
2 s:iterator: 获取值栈list集合数据,表示list集合
3 s:debug: 查看值栈结构和数据
Struts2表单标签
html表单标签
-
(1)form : action、method、enctype (2)输入项 - 大部分在input里面封装 type=”值” - text:普通输入项 - password:密码输入项 - radio:单选输入项 - checkbox:复选输入项 - file:文件上传项 - hidden:隐藏项 - button:普通按钮 - submit:提交按钮 - image:图片提交 - reset:重置 - select:下拉输入项 - textarea:文本域
struts2总结
1 Action
(1)action创建(继承ActionSupport类)
(2)配置访问action的方法(通配符)
(3)action获取表单数据
(4)action操作域对象
(5)result标签里面type属性
2 值栈
(1)值栈结构
(2)向值栈放数据
(3)从值栈获取数据
3 拦截器
(1)拦截器原理
(2)自定义拦截器
- 继承类
- 写拦截器逻辑
- 配置拦截器
– 配置让action某些方法不进行拦截