值栈
什么是值栈:
1.0 web阶段学习过servlet,在servlet里面吧数据放到域对象里面(request、session、servletContext域),到页面中获取到域对象里面的值(EL表达式)
2.0在struts2的action里面,除了把数据放到域对象,还可以吧数据放到值栈里面,在页面中获取到值栈数据
3.0值栈是struts2里面提供存储方式,值栈类似于域对象,把数据放到值栈里面,在页面中获取到值栈数据,值栈可以存值和取值结构。
4.0重要概念:servlet和action的区别
(1)Servlet:servlet默认在第一次访问的时候创建,servelt创建一次,即单实例对象;
(2)Action:Action在访问的时候创建,Action创建多次,每次访问action时候,都会创建新的action对象,是一个多实例对象;
5.0 值栈存储的位置:
(1)每次访问action的时候就会创建一个action对象,在每个action对象中都有一个(仅有一个)值栈对象,获取值栈对象的方法:
值栈的存储位置:
5.0 值栈存储的位置:
(1)每次访问action的时候就会创建一个action对象,在每个action对象中都有一个(仅有一个)值栈对象,获取值栈对象的方法:
注:这两个值栈是同一个值栈,因为每个action对象中有且仅有一个值栈对象存在。
获取值栈对象(常用):
1 在action获取值栈对象有多种方式
(1)常用方式
第一步 获取ActionContext对象
第二步 调用ActionContext对象里面的方法得到值栈对象
//1.获取ActionContext对象
ActionContext context=ActionContext.getContext()
//2. 调用ActionContext对象的方法:
ValueStack stack=context.getValueStack();
值栈内部结构:
1 值栈结构分为两部分
第一部分 root,是list集合
第二部分 context,是map集合
2 一般操作都是操作root里面数据
3 context里面是key-value结构,key值是固定的,value存储对象引用
4 在struts2里面提供标签库,有一个标签,这个标签可以查看值栈内部结构
(1)debug标签
[Debug]
(2)root中的结构,在其中栈顶元素,默认是Action引用,如下图中的BookAction。
在每个action对象里面有一个值栈对象;
在值栈对象里面有action对象引用
值栈的特点:
(1)值栈结构分为两部分:
第一部分root:是list集合
第二部分context:是map集合
(2)我们一般操作的都是root中的数据
(3)context里面是key-value结构,key值是固定的,value存储的是对象的引用
(4)在struts2里面提供标签库,有一个标签,这个标签可以查看值栈内部结构
>
>栈顶元素:默认的是action的引用
在每个action对象里面都有一个值栈对象
在值栈里面有一个action对象引用
向值栈中放数据:
1.向值栈放数据,有三种方法:
第一种方式:先获取值栈对象,再调用值栈中set方法进行存值。
//1.获取值栈对象
ActionContext context=ActionContext.getContext();
ValueStack stack=context.getValueStack();
//2.调用值栈对象里面的set方法;
stack.set("username","张萍");
第二种方式:先获取值栈对象,在调用其中的push方法进行存值。
//调用值栈对象里面的push方法;
stack.push("张萍"); //在值栈中存入一个String对象
第三种方式(我们一般用的是这种方式):在action成员变量位置定义变量,生成get方法;
//1.定义变量
private String usename;
//2.生成变量的get方法;
public String getUsername() {
return username;
}
public String execute() {
//3.向值栈中变量设置值;
username="张萍";
}
注:
(1)使用set或者push方法向值栈中存储数据,会重新分配空间进行存储;
(2)使用第三种方式向值栈中存入数据,不会重新分配空间,而是放到action对象引用里面。
1.向值栈中放对象:
1.在action定义对象类型变量
2 生成变量的get方法
3 在方法中向对象里面设置值,即初始化变量值;
如下:
2.向值栈中放入list集合:
1 定义List类型变量
2 生成get方法
3 在方法中向list里面设置值
如下:
从值栈中获取数据:
1 在action里面把数据放到值栈里面,在jsp页面中获取值栈数据
2 ognl概述
(1)ognl是表达式,之前学过el表达式,el表达式在jsp中获取域对象里面值
Ognl表达式比el表达式更加强大,使用ognl在jsp和struts2标签一起使用获取值栈数据
1.获取值栈中的字符串:
<!--获取值栈字符串值
<s:property value=""/>
-->
<s:property value="username"/>
2.获取值栈中的对象的值:
<s:property value="user.username"/>
<s:property value="user.password"/>
3.获取值栈中的list集合:
第一种方式:
<s:property value="list[0].username"/>
<s:property value="list[0].password"/><br/>
<s:property value="list[1].username"/>
<s:property value="list[1].password"/>
第二种方式:
//类似于forEach标签,s:iterator标签
<s:iterator value="list">
<s:property value="username>
<s:property value="passoword>
</s:iterator>
第三种方式:
<s:iterator value="list" var="user">
<!--执行的机制:
现在操作的数据在root里面
(1)遍历得到值栈里面的list集合数据
(2)iterator标签里面添加属性var集合,var属性就是每次遍历list集合得到user对象
(3)添加var之后,把每次遍历得到的user对象放到context里面;
(4)需要从context里面获得对象;
(5)从context获取对象值,必须添加符号:#
-->
<s:property value="username>
<s:property value="passoword>
</s:iterator>
EL表达式获取值栈中的数据:
1 el表达式在jsp页面中获取域对象里面的值
2 在jsp页面中使用el表达式把值栈数据获取出来,如下:
3 为什么el从值栈获取数据
(1)EL表达式功能获取域对象里面数据
(2)底层对request对象里面的getAttribute方法进行增强
- 调用getAttribute方法从域对象里面获取值,如果可以获取到直接返回
- 从域对象里面如果获取不到值,获取值栈对象,从值栈里面把值获取出来,再放到域对象里面
拦截器
什么是拦截器:
在struts2框架中,实现的功能都是在拦截器中实现的。拦截是AOP(Aspect-Oriented Programming)的一种实现策略。
它提供了一种机制,是开发者可以定义一个在action执行前组织期执行,同时也提供了一种增强原有的代码功能的方式。
拦截器概述:
在struts2框架里面有很多的拦截器,但是这些拦截器不是都执行,每次执行一些默认拦截器,如下图:
拦截器在什么时候执行:
在action对象创建之后,action的方法执行之前进行执行
拦截器的底层原理:
拦截器底层原理主要两部分:
第一部分 AOP思想
(1)面向切面(方面)编程
(2)有基本功能,扩展基本功能,原始做法修改源代码实现,按照aop思想,不修改源代码方式扩展功能
第二部分 责任链模式
(1)责任链模式是java设计模式
(2)责任链模式描述:
执行一组操作(很多操作),有添加操作、有修改操作,首先执行添加操作操作,添加操作执行之后做类似于放行操作,再执行修改操作,依次类推...
通过:return invocation.invoke(); 来实现放行的操作。
(3)过滤链
自定义拦截器(重点):
拦截器的结构:
(1)在实际的开发过程中,如果自己写拦截器,需要继承其他的拦截器类:
---通过继承MethodFilterInterceptor 类。
在实际的开发中,如果自己写拦截器:
-可以自己写类,然后继承AbstractInterceptor
-建议继承MethodFilterInterceptor类
自定义登录拦截器需求介绍:
(1)在项目中,只有登录状态才可以点击action超链接,如果不是登录,点击action超链接回到登录页面重新进行登录
- 登录状态:使用session域对象判断
配置拦截器和action关系(注册拦截器):
(1)在struts.xml声明拦截器:
<package name="demo" extecds="struts-default" namespace="/">
<!--声明拦截器-->
<interceptors>
<interceptor name="loginintercept" class="(全路径)">
</interceptors>
(2)在具体的action使用声明的拦截器
<action name="customer_*" class="(全路径)">
<!--使用拦截器-->
<interceptor-ref name="loginintercept"></interceptor-ref>
loginintercept是自定义拦截器。