1.OGNL表达式语言 相对EL表达式,它提供了平时我们需要的一些功能,如: Ognl 有一个上下文(Context)概念,说白了上下文就是一个MAP结构,它实现了java.utils.Map接口,在Struts2中上下文(Context)的实现为ActionContext,下面是上下文(Context)的结构示意图
另外OGNL会设定一个根对象(root对象),在Struts2中根对象就是ValueStack(值栈) 。如果要访问根对象(即ValueStack)中对象的属性,则可以省略#命名空间,直接访问该对象的属性即可。 在struts2中,根对象ValueStack的实现类为OgnlValueStack,该对象不是我们想像的只存放单个值,而是存放一组对象。在OgnlValueStack类里有一个List类型的root变量,就是使用他存放一组对象 在root变量中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问root变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。 3.由于ValueStack(值栈)是Struts 2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的EL表达式访问ValueStack(值栈)中对象的属性: 如果访问其他Context中的对象,由于他们不是根对象,所以在访问时,需要添加#前缀。 session对象:用来访问HttpSession,例如#session.userName或者#session['userName'],相当于调用session.getAttribute("userName")。 request对象:用来访问HttpServletRequest属性(attribute)的Map,例如#request.userName或者#request['userName'],相当于调用request.getAttribute("userName")。 parameters对象:用于访问HTTP的请求参数,例如#parameters.userName或者#parameters['userName'],相当于调用request.getParameter("username")。 attr对象:用于按page->request->session->application顺序访问其属性。 4.为何使用EL表达式能够访问valueStack中对象的属性 原因是Struts2对HttpServletRequest作了进一步的封装。简略代码如下: public class StrutsRequestWrapper extends HttpServletRequestWrapper { 5.采用OGNL表达式创建List/Map集合对象 如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。 生成一个Map对象: Set标签用于将某个值放入指定范围。
not in表达式: 7.OGNL表达式的投影功能 8.property标签
10.if/elseif/else标签 10.url标签 <s:url action="helloworld_add" namespace="/test"><s:param name="personid" value="23"/></s:url> 当标签的属性值作为字符串类型处理时, “%”符号的用途是计算OGNL表达式的值。
如果集合为list 如果集合为MAP
生成如下html代码: 13.表单标签_radio单选框 14.表单标签_select下拉选择框 |
__________________________________________________________________________
其实 OGNL 获取 Context 中的对象中的属性的方法很简单: person.name 就可以获取 person 对象的 name 属性的值。 OGNL 会从当前 valueStack 开始查找所要求的属性,一直往上层查找,直到找到为止。
除此之外, Struts2 还提供了一些命名对象,它们存在于 Stack Context 中,所以访问这些对象时需要使用 # 前缀来指明。
1 , parameters 对象,用于访问 HTTP 请求参数。如 #parameters['foo'] 或 #parameters.foo ,用于返回调用 HttpServletRequest.getParameter("foo") 的返回值。
2 , request 对象,用于访问 HttpServletRequest 的属性。如 #request['foo'] 或 #request.foo ,用于返回调用 HttpServletRequest.getAttribute("foo") 的返回值。
3 , session 对象,用于访问 HttpSession 的属性。如 #session['foo'] 或 #session.foo ,用于返回调用 HttpSession.getAttribute("foo") 的返回值。
4 , application 对象,用于访问 ServletContext 的属性。如 #application['foo'] 或 #application.foo ,用于返回调用 ServletContext.getAttribute("foo") 的返回值。
5 , attr 对象,如果可以访问到,则访问 PageContext ,否则将依次搜索如下对象: HttpServletRequest, HttpSession , ServletContext 中的属性。
OGNL 表达式还可以直接生成一个集合,如:
{e1,e2,e3} 可以生成一个 List ;多个元素之间以英文逗号分隔。
#{key1:value1,key2:value2} 可以生成一个 Map ; key-value 之间以英文冒号分隔,多个元素之间以英文逗号分隔。
OGNL 还提供了两个元素符: in 和 not in , in 判断某个元素是否在指定的集合中, not in 判断某个元素是否不在指定集合中。如下例:
<s:if test="'foo'" in {'foo','fooo'} > 包含 </s>
<s:if test="'foo'" not in {'foo','fooo'} > 不包含 </s>
除此之后, OGNL 还允许通过某个规则取得集合的子集。取得子集时有如下 3 个操作符:
1 , ? 取出所有符合选择逻辑的元素
2 , ^ 取出符合选择逻辑的第一个元素
3 , $ 取出符合选择逻辑的最后一个元素
如以下代码: person.relatives.{? #this.gender == 'male'}
直接在集合后紧跟 .{} 运算符表明用于取出该集合的子集,在 {} 内使用 ? 表明取出所有符合选择逻辑的元素,而 #this 代表集合里元素。因此,上面代码的含义是:取出 person 里所有的 gender 等于 male 的 relatives 的属性的集合。
OGNL 支持基本的 Lambda( λ ) 表达式语法。通过这种 Lambda 表达式语法,可以让我们在 OGNL 表达式中使用一些简单的函数。如下面的斐波那契数列:
if n==0 return 0;
elseif n==1 return 1;
else return fib(n-2)+fib(n-1);
fib(0)=0
fib(1)=1
fib(11)=89
我们可以使用 OGNL 表达式来求该数列中第 11 个元素的值:
<s:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2) + #fib(#this-1)], #fib(11)" />
用 OGNL 表达式取出 valueStack 中的值的方式为 ${requtestScope.username};
------------------------------------------------------------------------------------------------------------------
OGNL就是<s:property value="username"/>标签中value里的内容。
<li>访问值栈中的action的普通属性: username = <s:property value="username"/> </li>
<li>访问值栈中对象的普通属性(get set方法):<s:property value="user.age"/> | <s:property value="user['age']"/> | <s:property value="user[\"age\"]"/> | wrong: <%--<s:property value="user[age]"/>--%></li>
<li>访问值栈中对象的普通属性(get set方法): <s:property value="cat.friend.name"/></li>
<li>访问值栈中对象的普通方法:<s:property value="password.length()"/></li>
<li>访问值栈中对象的普通方法:<s:property value="cat.miaomiao()" /></li>
<li>访问值栈中action的普通方法:<s:property value="m()" /></li>
<hr />
<li>访问静态方法:<s:property value="@com.bjsxt.struts2.ognl.S@s()"/></li>
<li>访问静态属性:<s:property value="@com.bjsxt.struts2.ognl.S@STR"/></li>
<li>访问Math类的静态方法:<s:property value="@@max(2,3)" /></li>
<hr />
<li>访问普通类的构造方法:<s:property value="new com.bjsxt.struts2.ognl.User(8)"/></li>
<hr />
<li>访问List:<s:property value="users"/></li>
<li>访问List中某个元素:<s:property value="users[1]"/></li>
<li>访问List中元素某个属性的集合:<s:property value="users.{age}"/></li>
<li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li>
<li>访问Set:<s:property value="dogs"/></li>
<li>访问Set中某个元素:<s:property value="dogs[1]"/></li>
<li>访问Map:<s:property value="dogMap"/></li>
<li>访问Map中某个元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap['dog101']"/> | <s:property value="dogMap[\"dog101\"]"/></li>
<li>访问Map中所有的key:<s:property value="dogMap.keys"/></li>
<li>访问Map中所有的value:<s:property value="dogMap.values"/></li>
<li>访问容器的大小:<s:property value="dogMap.size()"/> | <s:property value="users.size"/> </li>
<hr />
<li>投影(过滤):<s:property value="users.{?#this.age==1}[0]"/></li>
<li>投影:<s:property value="users.{^#this.age>1}.{age}"/></li>
<li>投影:<s:property value="users.{$#this.age>1}.{age}"/></li>
<li>投影:<s:property value="users.{$#this.age>1}.{age} == null"/></li>
<hr />
<li>[]:<s:property value="[0].username"/></li>