ContextMap(值栈)与OGNL表达式
- OGNL基本语法
OGNL—强大的表达式语言,类似于jsp中的el表达式,可以存取对象的任意属性,调用对象的 方法,实现字段类型的转换
OGNL表达式的特点:
1)是一门功能强大的表达式语言,可以存取对象的属性,调用对象的方法
2)OGNL是struts2默认支持的语言
3)在Struts2的程序中,必须使用struts2标签来使用OGNL表达式
在Struts2中使用OGNL表达式:
1)先导入Struts2标签:
2)编写OGNL表达式
OGNL表达式的语法是:%{OGNL表达式}
EL表达式:${name},到四个域的范围内查询name数据
OGNL表达式到哪里找数据?
答案:OGNL表达式是到OGNLContext找数据(OGNL上下文,其实就是ContextMap)
OGNL表达式简写方式:OGNL表达式
OGNL表达式表示字符串:单引号 ‘OGNL表达式’
OGNL表达式调用对象的成员方法:
OGNL表达式调用类的静态属性:
调用类的静态属性:@限定名的类@静态属性
OGNL表达式调用类的静态方法:
调用类的静态方法:@限定名的类@静态方法
注意事项:Struts2默认是没有开启类的静态方法调用
如果需要使用,那么需要通过常量开启类的静态方法调用
default.properties中:strutsognl.allowStaticMethodAccess=false
在Struts.xml中开启
案例:
语法5:OGNL可以创建List集合(开发中常用)
{‘元素1’,’元素2’}
{‘元素1’,’元素2’}这个语法的底层:
List list = new ArrayList();
list.add(“男”);
list.add(“女”);
语法6:OGNL表达式创建Map集合:#{key:value,key:value}
key和value值不同的情况
复选框:多个可选择
EL表达式只能获取对象的属性,不能创建对象,但是OGNL可以
- ContextMap数据结构
OGNLContext(OGNL上下文对象)就是一个Map集合,称为ContextMap集合。这个ContextMap的作用,就是用户和Struts2进行数据交换(传输)
ContextMap对象:封装用户的请求相关的数据;可以把后台查询的数据保存到ContextMap中
ContextMap代替了域对象那些,比域对象功能更强大
- ActionContext工具类的使用
这个ActionContext是个工具类,用于操作ContextMap的工具类,这个对象里面提供了许多关于存取ContextMap对象数据的
ActionContext:
构造方法:
传入一个ContextMap;
里边有put、get、getSession方法等
通过对ActionContext底层源码的分析,ActionContext对象需要ContextMap来构建,构建完成之后,提供了一些put和get方法来操作ContextMap
- *ContextMap和ActionContext源码分析
通过核心过滤器找到
StrutsPrepareAndExecuteFileter
doFilter方法:
每一次请求发出都会走逻辑
ActionContext是线程安全的,每一次请求都是一个线程,得采用不同的对象去存储
如何保证ActionContext的线程安全性:
采用ThreadLocal来保证
ActionContext是线程安全的
创建新的ActionContext对象
整体结构:
- ContextMap操作数据(存取数据———重点)
新建Action,继承ActionSupport
在execute中写入
public String execute() throws Exception {
//保存数据ContextMap对象中
//1.往ContextMap(大Map)保存数据
ActionContext ac = ActionContext.getContext();//从当前线程1.拿到当前线程的Context对象
ac.put("contextMap","这是ComtextMap的数据");
/2./往RequestMap保存数据
HttpServletRequest request = (HttpServletRequest)ac.get(StrutsStatics.HTTP_QEQUEST);
request.setAttribute("RequestMap","requestMap的数据");
//3.往SessionMap中保存数据
ac.getSession.put("seesionMap","sessionMap的数据");
//4.往application保存数据
ac.getApplication().put("applicationMap","applicationMap");
}
s:debug标签可以用来调试contextMap中的数据
<s:debug/>
在Action中保存数据,获取数据,是在页面上获取(引入Struts2标签来获取)
valueStack(值栈)
ValueStack是一个接口,这个接口的实现类是OgnlValueStack,这个是实现类里面的root变量才是真正存放数据的地方,本质是一个CopyOnWriteList ,root是一个list集合,但是这个存放数据的方式类似于栈,模拟栈的结构
CompoundRoot对象里面有三种方法,这三个方法就是操作值栈对象的核心方法:
push核心方法,往list集合里面添加数据,永远往第一个位置放入,模拟进栈方法,新添加元素一直在栈顶
push():这个方法把对象放入到值栈的栈顶元素
pop():这个方法取出值栈的栈顶元素(移除)
peek():获取到值栈的栈顶元素
ValueStack存取数据
1.在Action往值栈保存数据
ActionContext ac = ActionContext.getContext();
ValueStack avs = ac.getValueStack();
vs.push(“小草”);
2.在页面上获取值栈数据
值栈的访问不需要带#标签:[0]:代表获取值栈中的第一个元素往后为止
规则:获取值栈的规则:默认情况,都是从栈顶元素往后查找,一直查找到最后一个元素为止
[0].top:代表第一个元素
[1].top:代表第二个元素
[0].top可以省略,代表只找第一个元素
值栈的访问不需要加#号
ContextMap访问需要带#号
- Struts2开发常用功能
Struts2表单验证–方法验证
Struts2的表单验证属于后台验证
在实际的项目中有必要做前台验证和后台验证,因为安全方面,可以绕过前端机制
方法(代码验证):
Action本身已经实现了Validateable接口
覆盖validate()方法:–可以进行方法验证:
配置input视图,当验证失败后struts2自动跳转到input视图
在页面上显示错误信息
XML验证
提供一个xml验证文件:
在Action下边写一个xml:Demo1Action-validation.xml
在strutscore下边有关于volidate的约束:
参考验证类型:
xml文件内容:
- Strust2文件上传下载
文件上传–底层原理是通过FileUploadInterceptor拦截器实现的
修改form表单的enctype属性
在Action接受文件和参数
注意必须有文件内容,文件名称和文件类型,前缀icon必须一致,后边是固定的
上传内容不能大于2m的文件,如果需要修改限制,则需要改变常量配置在struts.xml中,这个是在default.properties中配置的:
文件下载:
Struts2是依靠一个stream的视图进行文件下载
编写一个Action
配置Action:
- Token令牌机制防重复提交
Struts设计了令牌的机制TokenInterceptor拦截器完成
1.在表单携带一个隐藏域:
每次生成一个随机数,拦截器会判断生成的随机数和保存的随机数是否一致
TokenInterceptor拦截器默认没有生效
默认拦截器栈中并没有
拦截器会生效—–
可以指定当重复提交时跳转的页面
- 使用Struts2注解开发
在Struts2里面是 完全可以通过注解开发的,代替xml配置的方式,强调”零配置“
注解需要引入新的包–注解包–插件包
可能需要asm的一些依赖包
注解的作用是代替xml配置文件
删除struts.xml
Action所在的包必须以这些结尾,扫描
在Action中加入注解元素