众所周知,Strut 2的Action类通过属性可以获得所有相关的值,如请求参数、Action配置参数、向其他Action传递属性值(通过chain结果)等等。要获得这些参数值,我们要做的唯一一件事就是在Action类中声明与参数同名的属性,在Struts 2调用Action类的Action方法(默认是execute方法)之前,就会为相应的Action属性赋值。
要完成这个功能,有很大程度上,Struts 2要依赖于ValueStack对象。这个对象贯穿整个Action的生命周期(每个Action类的对象实例会拥有一个ValueStack对象)。当Struts 2接收到一个.action的请求后,会先建立Action类的对象实例,但并不会调用Action方法,而是先将Action类的相应属性放到ValueStack对象的顶层节点(ValueStack对象相当于一个栈)。只是所有的属性值都是默认的值,如String类型的属性值为null,int类型的属性值为0等。
在处理完上述工作后,Struts 2就会调用拦截器链中的拦截器,当调用完所有的拦截器后,最后会调用Action类的Action方法,在调用Action方法之前,会将ValueStack对象顶层节点中的属性值赋给Action类中相应的属性。大家要注意,在这里就给我们带来了很大的灵活性。也就是说,在Struts 2调用拦截器的过程中,可以改变ValueStack对象中属性的值,当改变某个属性值后,Action类的相应属性值就会变成在拦截器中最后改变该属性的这个值。
从上面的描述很容易知道,在Struts 2的的Action类可以获得与属性同名的参数值就是通过不同的拦截器来处理的,如获得请求参数的拦截器是params,获得Action的配置参数的拦截器是staticParams等。在这些拦截器内部读取相应的值,并更新ValueStack对象顶层节点的相应属性的值。而ValueStack对象就象一个传送带,将属性值从一个拦截器传到了另一个拦截器(当然,在这其间,属性值可能改变),最后会传到Action对象,并将ValueStack对象中的属性的值终值赋给Action类的相应属性
拦截器的源代码:packageinterceptors;
importjava.util.Enumeration;
importjava.util.Map;
importjava.util.Properties;
importjava.io.InputStream;
importjava.io.FileInputStream;
importcom.opensymphony.xwork2.ActionContext;
importcom.opensymphony.xwork2.ActionInvocation;
importcom.opensymphony.xwork2.config.entities.ActionConfig;
importcom.opensymphony.xwork2.interceptor.AbstractInterceptor;
importcom.opensymphony.xwork2.util.ValueStack;
publicclassPropertyInterceptorextendsAbstractInterceptor
{
privatestaticfinalStringDEFAULT_PATH_KEY="path";
privatestaticfinalStringDEFAULT_ENCODING_KEY="encoding";
privatestaticfinalStringDEFAULT_SEPARATOR_KEY="separator";
protectedStringpathKey=DEFAULT_PATH_KEY;
protectedStringencodingKey=DEFAULT_ENCODING_KEY;
protectedStringseparatorKey=DEFAULT_SEPARATOR_KEY;
publicvoidsetPathKey(StringpathKey)
{
this.pathKey=pathKey;
}
publicvoidsetEncodingKey(StringencodingKey)
{
this.encodingKey=encodingKey;
}
publicvoidsetSeparatorKey(StringseparatorKey)
{
this.separatorKey=separatorKey;
}
@Override
publicStringintercept(ActionInvocationinvocation)throwsException
{
ActionConfigconfig=invocation.getProxy().getConfig();
Map<String,String>parameters=config.getParams();
if(parameters.containsKey(pathKey))
{
Stringpath=parameters.get(pathKey);
Stringencoding=parameters.get(encodingKey);
Stringseparator=parameters.get(separatorKey);
if(encoding==null)
encoding="UTF-8";
if(separator==null)
separator="";
path=invocation.getAction().getClass().getResource(path)
.getPath();
Propertiesproperties=newProperties();
InputStreamis=newFileInputStream(path);
java.io.Readerreader=newjava.io.InputStreamReader(is,encoding);
properties.load(reader);
ActionContextac=invocation.getInvocationContext();
ValueStackstack=ac.getValueStack();
System.out.println(stack.hashCode());
Enumerationnames=properties.propertyNames();
while(names.hasMoreElements())
{
// 下面会使用setValue方法修改ValueStack对象中的相应属性值
Stringname=names.nextElement().toString();
if(!name.contains("."))
stack.setValue(name,properties.get(name));
StringnewName=null;
newName=parameters.get(name.replaceAll(".",""));
if(newName!=null)
stack.setValue(newName,properties.get(name));
if(!separator.equals(""))
{
newName=name.replaceAll(".","");
stack.setValue(newName,properties.get(name));
}
newName=name.replaceAll(".",separator);
stack.setValue(newName,properties.get(name));
}
}
returninvocation.invoke();
}
}
ognl标签用法:
访问属性
名字属性获取 :<s:property value="user.username"/><br>
地址属性获取 :<s:property value="user.address.addr"/><br>
|
访问方法
调用值栈中对象的普通方法: <s:property value="user.get()"/><br>
|
访问静态属性和方法
调用 Action 中的静态方法: <s:property value="@struts.action.LoginAction@get()"/>
调用 JDK 中的类的静态方法: <s:property value="@java.lang.Math@floor(44.56)"/><br>
调用 JDK 中的类的静态方法 ( 同上 ) : <s:property value="@@floor(44.56)"/><br>
调用 JDK 中的类的静态方法: <s:property value="@java.util.Calendar@getInstance()"/><br>
调用普通类中的静态属性: <s:property value="@struts.vo.Address@TIPS"/><br>
|
访问构造方法
调用普通类的构造方法 :<s:property value="new struts.vo.Student(' 王老吉 ' , ' 爱国饮料 ' , 3 , 99).username"/>
|
1.5. 访问数组
获取 List:<s:property value="testList"/><br>
获取 List 中的某一个元素 ( 可以使用类似于数组中的下标获取 List 中的内容 ):
<s:property value="testList[0]"/><br>
获取 Set:<s:property value="testSet"/><br>
获取 Set 中的某一个元素 (Set 由于没有顺序,所以不能使用下标获取数据 ):
<s:property value="testSet[0]"/><br> ×
获取 Map:<s:property value="testMap"/><br>
获取 Map 中所有的键 :<s:property value="testMap.keys"/><br>
获取 Map 中所有的值 :<s:property value="testMap.values"/><br>
获取 Map 中的某一个元素 ( 可以使用类似于数组中的下标获取 List 中的内容 ):
<s:property value="testMap['m1']"/><br>
获取 List 的大小 :<s:property value="testSet.size"/><br>
|
访问集合 – 投影、选择 (? ^ $)
利用选择获取 List 中成绩及格的对象 :<s:property value="stus.{?#this.grade>=60}"/><br>
利用选择获取 List 中成绩及格的对象的 username:
<s:property value="stus.{?#this.grade>=60}.{username}"/><br>
利用选择获取 List 中成绩及格的第一个对象的 username:
<s:property value="stus.{?#this.grade>=60}.{username}[0]"/><br>
利用选择获取 List 中成绩及格的第一个对象的 username:
<s:property value="stus.{^#this.grade>=60}.{username}"/><br>
利用选择获取 List 中成绩及格的最后一个对象的 username:
<s:property value="stus.{$#this.grade>=60}.{username}"/><br>
利用选择获取 List 中成绩及格的第一个对象然后求大小 :
<s:property value="stus.{^#this.grade>=600}.{username}.size"/><br>
|
集合的伪属性
OGNL 能够引用集合的一些特殊的属性 , 这些属性并不是 JavaBeans 模式 , 例如 size(),length() 等等 . 当表达式引用这些属性时 ,OGNL 会调用相应的方法 , 这就是伪属性 .
集合
|
伪属性
|
Collection(inherited by Map, List & Set)
|
size ,isEmpty
|
List
|
iterator
|
Map
|
keys , values
|
Set
|
iterator
|
Iterator
|
next , hasNext
|
Enumeration
|
next , hasNext , nextElement , hasMoreElements
|
Lambda :[…]
格式: :[…]
使用 Lambda 表达式计算阶乘 :
<s:property value="#f = :[#this==1?1:#this*#f(#this-1)] , #f(4)"/><br>
|
OGNL 中 # 的使用
# 可以取出堆栈上下文中的存放的对象 .
名称
|
作用
|
例子
|
parameters
|
包含当前 HTTP 请求参数的 Map
|
#parameters.id[0] 作用相当于
request.getParameter("id")
|
request
|
包含当前 HttpServletRequest 的属性( attribute) 的 Map
|
#request.userName 相当于
request.getAttribute("userName")
|
session
|
包含当前 HttpSession 的属性( attribute )的 Map
|
#session.userName 相当于
session.getAttribute("userName")
|
application
|
包含当前应用的 ServletContext 的属性( attribute )的 Map
|
#application.userName 相当于
application.getAttribute("userName")
|
attr
|
用于按 request > session > application 顺序访问其属性( attribute )
|
|
获取 Paraments 对象的属性: <s:property value="#parameters.username"/>
OGNL 中 % 的使用
用 %{} 可以取出存在值堆栈中的 Action 对象 , 直接调用它的方法 .
例如你的 Action 如果继承了 ActionSupport . 那么在页面标签中,用 %{getText('key')} 的方式可以拿出国际化信息 .
OGNL 中 $ 的使用
“ $ ”有两个主要的用途
l 用于在国际化资源文件中,引用 OGNL 表达式
l 在 Struts 2 配置文件中,引用 OGNL 表达式
值栈
ValueStack 对象。这个对象贯穿整个 Action 的生命周期(每个 Action 类的对象实例会拥有一个 ValueStack 对象)。当 Struts 2 接收到一个 .action 的请求后,会先建立 Action 类的对象实例,但并不会调用 Action 方法,而是先将 Action 类的相应属性放到 ValueStack 对象的顶层节点( ValueStack 对象相当于一个栈)。
在 Action 中获得 ValueStack 对象: ActionContext.getContext().getValueStack()
l Top 语法
使用 Top 获取值栈中的第二个对象 :<s:property value="[1].top. 对象 "/>
l N 语法
使用 N 获取值栈中的第二个对象 :<s:property value="[1]. 对象 "/>
l @ 语法
调用 action 中的静态方法: <s:property value="@vs1@ 静态方法 "/> vs :值栈 1 :表示第一个。
分享到:
相关推荐
struts2--3.Ognl与值栈
主要介绍了Java的Struts框架中栈值和OGNL的使用,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
1、什么是值栈 2、值栈的内部结构 3、ActionContext和ValueStatck的关系 4、如何获取值栈对象 5、向值栈存数据 6、从值栈中获取数据
struts2 OGNL之标签访问值栈(value stack)用法,希望能对大家有帮助
值栈(ValueStack)是Struts2的一个核心概念,类似于正常的栈,符合后进先出的 栈的特点,可以在值栈中放入、删除和查询对象。Strtus2对OGNL进行了扩充,将值栈作为OGNL的根对象。 什么是值栈?符合先进后出的特点,能给...
3.由于ValueStack(值栈)是Struts 2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性 4.为何使用EL表达式能够访问valueStack中对象的属性 原因...
Struts2入门介绍、环境配置与基本操作演示,包含OGNL,值栈与域概念
1.值栈入门 22 2.OGNL入门 24 3.普通方法访问 24 4.静态方法访问 24 5.默认类Math的访问 24 6.调用普通类的构造方法 25 7.集合对象初步 25 8.集合对象进阶 25 9.N语法top语法 26 10.获取Stack Context中的信息 26 11...
对Struts2框架中的相关知识还有困惑的同学有福了,此次上传的是西安领航何足道老师的核心项目Struts2部分的重点难点的归纳总结,...主要包括的知识有Action的动态调用方法、值栈、拦截器、ActionContext、Ognl表达式等
1、 ValueStack其实就是一个放置Java对象的堆栈而已,唯一特别的是可以使用EL来获得值堆栈中对象属性的数据,并可以为值堆栈的对象属性赋值。 2、 EL,全称Express Language,即表达式语言。不要被语言吓倒,它是...
本压缩包包含完整struts2的完整讲义,其中涉及struts2的快速入门、struts的开发流程、常用配置、数据封装的两种方式、OGNL、值栈deng
该资源包含了所有struts2的知识点,从基本的配置到拦截器再到ognl的值栈,应有尽有,很值得一看,对于刚学过struts2的同学,看看可以更深刻的理解其中的原理。
总结了ognl , 值栈,向值栈中放数据获取数据,拦截器,国际化资源的使用,校验器
Struts2框架框架使用OGNL语言和值栈技术实现数据的流转处理。下面通过本文给大家分享struts2数据处理的相关知识,感兴趣的朋友参考下吧
2.6.2 定义和使用拦截器栈 97 2.6.3 使用自定义拦截器 98 2.7 小结 100 第3章 struts 2标签库详解与ajax技术应用 103 3.1 struts 2主题与模板 103 3.2 struts 2控制标签详解 105 3.2.1 if/elseif/else标签详解...
5.4值栈与ognl表达式 100 5.5struts2的标签库 103 5.5.1控制标签 103 5.5.2数据标签 104 5.5.3表单标签 105 5.5.4非表单ui标签 107 本章小结 108 课后练习 109 第6章struts2高级应用 110 6.1拦截器 110 ...
Struts2框架介绍、工作原理与架构分析、6大配置文件分析使用通配符定义action、动态方法调用,ActionContext及ServletActionContext...默认拦截器分析、自定义拦截器、OGNL表达式、值栈分析及操作、标签、 json使用。