Ognl表达式

原创 2012年03月28日 09:17:07

 

一、"#"的用法
   1、 访问OGNL上下文和Action上下文,#相当于ActionContext.getContext();下表有几个ActionContext中有用的属性: 
        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) #attr.userName相当于按顺序在以上三个范围(scope)内读取userName属性,直到找到为止
   

  2、用于过滤和投影(projecting)集合,如books.{?#this.price<100};
    

3、构造Map,如#{'foo1':'bar1', 'foo2':'bar2'}。


二、"%"的用法
   

 “%”符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。例如在Ognl.jsp中加入以下代码:
    <h3>%的用途</h3>
    <p><s:url value="#foobar['foo1']" /></p>
    <p><s:url value="%{#foobar['foo1']}" /></p>


三、"$"的用法
    1、用于在国际化资源文件中,引用OGNL表达式
    2、在Struts 2配置文件中,引用OGNL表达式
     例如:
         <action name="AddPhoto" class="addPhoto">
            <interceptor-ref name="fileUploadStack" />           
            <result type="redirect">ListPhotos.action?       albumId=${albumId}</result>
        </action>

 

 

 


struts2中的OGNL上下文
struts2对OGNL上下文的概念又做了进一步扩充,在struts2中,OGNL上下文通常如下所示:
|–request
|
|–application
|
context map—|–OgnlValueStack(root) [ user, action, OgnlUtil, ... ]
|
|–session
|
|–attr
|
|–parameters

我们可以使用”#requet”访问HttpServletRequest对象, “#session”访问HttpSession对象,但请注意”根对象”是什么?是ValueStack!
那么ValueStack是什么?值栈。也就是一组对象的堆栈。也就是说,在struts2中,根对象不是我们通常的一个对象,而是一组对象。我们可以 push新的对象到值栈中,也可以弹出值栈的栈顶对象。如上图所示,假设我们将user对象push到值栈中,那么如下的表达式将与之前我们见过的表达式一样,具有相同的结果:
Java代码
name // 取用户的姓名
age // 取用户年龄
birthday // 取用户生日
customer.name // 取用户所属客户的名称
#request.parameters // 取请求参数

也就是说,我们使用name这个表达式的时候,ONGL会取”根对象”的name属性,但现在根对象是ValueStack!那么访问 ValueStack的name属性意味着什么呢?这意味着: ValueStack会先查看栈顶元素是否有name属性,如果有就返回该属性值,否则取出栈顶下的元素,继续查看,直到栈底为止。

关于ValueStack

Struts2的Action类通过属性可以或得所有相关的值,如请求参数、action配置参数、向其他Action传递属性值(通过Chain结果)等等。

要获得这些参数值,我们要做的唯一一件事就是在Action类中声明与参数同名的属性,在Struts2调用Action类的Action方法之前,就会为相应的Action属性赋值,要完成这个功能,有很大程度上,Struts2要依赖ValueStack对象。这个对象贯穿整个Action的生命周期(每个Action类的对象实例会拥有一个ValueStack对象)。当Struts2接收到一个.action的请求后,会先建立Action类的对象实例,但并不会调用Action方法,而是先将Action类的相应属性放到ValueStack对象的顶层节点(ValueStack对象相当于一个栈)。只是所有的属性值都是默认的值,如String类型的属性值为null,int类型的属性值为0等。处理完上述工作后,Struts2就会调用拦截器链中的拦截器,当调用完所有的拦截器后,最后会调用Action类的Action方法,在调用Action方法之前,会将ValueStack对象顶层节点中的属性值赋给Action类中相应的属性,注意,在这里就给我们呆了很大的灵活性。也就是说,在Struts2调用拦截器的过程中,可以改变ValueStack对象中属性的值,当改变某个属性之后,Action类的相应属性值就会变成在拦截器中最后改变该属性的这个值。

从上面的描述很容易知道,在Struts2的Action类可以获得与属性同名的参数值就是通过不同的拦截器来处理的,如获得请求参数的拦截器是params,获得Action的配置参数的拦截器是staticParams等,在这些拦截器内部读取相应的值,并更新ValueStack对象顶层节点的相应属性的值。而ValueStack对象就像一个传送带,将属性的值从一个拦截器传到了另一个拦截器(当然,在这期间,属性值可能改变),最后会传到Action对象,并将ValueStack对象中的属性的值的终值赋给Action类的相应属性。

1、值栈(ValueStack)
Struts2将OGNL上下文设置为Struts2中的ActionContext(内部使用的仍然是OgnlContext),并将值栈设为OGNL的根对象。
我们知道,OGNL上下文中的根对象可以直接访问,不需要使用任何特殊的“标记”,而引用上下文中的其他对象则需要使用“#”来标记。由于值栈是 上下文中的根对象,因此可以直接访问。那么对于值栈中的对象该如何访问呢?Struts2提供了一个特殊的OGNLPropertyAccessor,它 可以自动查找栈内的所有对象(从栈顶到栈底),直接找到一个具有你所查找的属性的对象。也就是说,对于值栈中的任何对象都可以直接访问,而不需要使用 “#”。
假设值栈中有两个对象:student和employee,两个对象都有name属性,student有学号属性number,而 employee有薪水属性salary。employee先入栈,student后入栈,位于栈顶,那么对于表达式name,访问的就是student 的name属性,因为student对象位于栈顶;表达式salary,访问的就是employee的salary属性。正如你所见,访问值栈中的对象属 性或方法,无须指明对象,也不用“#”,就好像值栈中的对象都是OGNL上下文中的根对象一样。这就是Struts2在OGNL基础上做出的改进。
2、[N]语法
如上所述,如果想要访问employee的name属性,应该如何写表达式呢?我们可以使用[N].xxx(N是从0开始的整数)这样的语法来指定从哪一个位置开始向下查找对象的属性,表达式[1].name访问的就是employee对象的name属性。
在使用[N].xxx语法时,要注意位置序号的含义,它并不是表示“获取栈中索引为N的对象”,而是截取从位置N开始的部分栈。
3、top关键字
top用于获取栈顶的对象,结合[N].xxx语法,我们就可以获取栈中任意位置的对象。
如:[0].top,[1].top等
4、访问静态成员
除了使用标准的OGNL表达式访问静态字段和静态方法外,Struts2还允许你不指定完整的类名,而是通过“vs”前缀来调用保存在栈中的静态字段和静态方法。
@vs@FOO_PROPERTY
@vs@someMethod()
@vs1@someMethod()
vs表示ValueStack,如果只有vs,那么将使用栈顶对象的类;如果在vs后面跟上一个数字,那么将使用栈中指定位置处的对象类。
5、值栈中的Action实例
Struts2框架总是把Action实例放在栈顶。因为Action在值栈中,而值栈又是OGNL中的根,所以引用Action的属性可以省略“#”标记,这也是为什么我们在结果页面中可以直接访问Action的属性的原因。

什么是OGNL表达式

前言     在经典的SSH框架中,我们在JSP页面经常会用到OGNL表达式来取值,然后赋值给页面元素,这种方式来赋值,JSP页面的代码看起来干净整洁,没有过多的Java代码。但是到底什么是...
  • u013038861
  • u013038861
  • 2016年08月01日 20:52
  • 2838

OGNL表达式语言详解

众所周知,OGNL充斥在Struts2前后台数据传递与存储的方方面面,给Struts2中数据的处理带来了极大的方便,所以,本次打算以两篇博客来介绍OGNL,第一篇就是脱离MVC框架,单纯介绍OGNL的...
  • yu102655
  • yu102655
  • 2016年08月11日 09:40
  • 22584

人生第一篇博客,求支持。 对EL表达式和JSTL标签库和OGNL表达式的了解

对EL表达式、JSTL标签库、还有OGNL表达式语言进行了描述。
  • sinat_23622505
  • sinat_23622505
  • 2015年12月22日 18:40
  • 769

OGNL表达式原理及使用

OGNL:object graph navigation language,对象图形导航语言,一种表达式语言。 为什么出现: 在我们所熟悉的mvc框架中,数据是在各层之间进行流转使用的。 显...
  • u013030682
  • u013030682
  • 2016年11月19日 10:29
  • 750

OGNL表达式的特殊的符号

OGNL表达式的特殊的符号 # 符号的用法 获得context中的数据 构建一个map集合 % 符号的用法 强制字符串解析成OGNL表达式。 ...
  • q547550831
  • q547550831
  • 2016年11月24日 20:31
  • 1383

OGNL表达式用法详解

表达式通常用来访问页面中的各种变量,进行结果输出. struts2中共支持以下几种表达式语言(默认的是OGNL): (1)OGNL:可以方便地操作对象属性的开源表达式语言; (2)JSTL:(J...
  • li2327234939
  • li2327234939
  • 2016年09月07日 15:00
  • 2461

OGNL表达式 #%$

1、“#”符号用途: (1)、访问非根对象(struts中值栈为根对象)如OGNL上下文和Action上下文,#相当于ActionContext.getContext();下表有几个Action...
  • xd0718
  • xd0718
  • 2011年10月01日 23:45
  • 492

关于Ognl表达式的过滤

List persons = new ArrayList(); Person p1 = new Person(); Person p2 = new Person(); Person p3 =...
  • u013803262
  • u013803262
  • 2014年11月01日 16:55
  • 474

Ognl表达式注入?命令执行?你来判断。

自评TCV = 0 泛微 E-Mobile 表达式注入?大概?这个洞是一个月以前,老师丢给我玩的,叫我学习一下。 拿到的时候一脸懵逼,什么是表达式注入?去漏洞库看了一圈。(・。・) 噢!原来可以执...
  • qq_27446553
  • qq_27446553
  • 2017年03月29日 22:32
  • 1749

OGNL表达式与EL表达式区别

1.显示页面**************************** /** 列表 */ public String list() throws Exception { List roleLis...
  • qq_28139371
  • qq_28139371
  • 2016年04月02日 11:18
  • 2484
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Ognl表达式
举报原因:
原因补充:

(最多只允许输入30个字)