http://blog.csdn.net/tjujacob/article/details/8117659

——————————————————————————————————————————————————————————

一、"#"的用法 
   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(root对象)-->parameters-->request -->session-->application

关于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类的相应属性值就会变成在拦截器中最后改变该属性的这个值。

①action属性-->valueStack

②valuestack赋值

③调用相应拦截器valuestack-->action属性

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

1、值栈(ValueStack)
Struts2将OGNL上下文设置为Struts2中的ActionContext(内部使用的仍然是OgnlContext),并将值栈设为OGNL的根对象。valuestack是ONGL的跟对象
我们知道,OGNL上下文中的根对象(valuestack)可以直接访问,不需要使用任何特殊的“标记”,而引用上下文中的其他对象则需要使用“#”来标记。
由于值栈是
上下文中的根对象,因此可以直接访问。那么对于值栈中的对象该如何访问呢?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的属性的原因。
6、Struts2中的命名对象
Struts2还提供了一些命名对象,这些对象没有保存在值栈中,而是保存在ActionContext中,因此访问这些对象需要使用“#”标记。这些命名对象都是Map类型。
parameters
用于访问请求参数。如:#parameters['id']或#parameters.id,相当于调用了HttpServletRequest对象的getParameter()方法。
注意,parameters本质上是一个使用HttpServletRequest对象中的请求参数构造的Map对象,一量对象被创建(在调用Action实例之前就已经创建好了),它和HttpServletRequest对象就没有了任何关系。
request
用于访问请求属性。如:#request['user']或#request.user,相当于调用了HttpServletRequest对象的getAttribute()方法。
session
用于访问session属性。如:#session['user']或#session.user,相当于调用了HttpSession对象的getAttribute()方法。
application
用于访问application属性。如:#application['user']或#application.user,相当于调用了ServletContext的getAttribute()方法。
attr
如果PageContext可用,则访问PageContext,否则依次搜索request、session和application对象。

struts2 OGNL ValueStack概念理解 # % $ 的区别的更多相关文章

  1. Struts2之ValueStack、ActionContext

    今天在看Action获取Resquest.Response时,发现了一个词:值栈.于是今天一天都在看,了解了值栈不仅能知道Action怎么获取request.response等这些,还会了解OGNL语 ...

  2. Struts2框架基础概念总结

    一.struts2框架 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的 ...

  3. Struts2(Ognl)

    OGNL(Object-Graph Navigation Language)全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整 ...

  4. Struts2:ValueStack

    一.ValueStack     1 .ValueStack是一个接口,在struts2中使用OGNL(Object-Graph Navigation Language)表达式实际上是使用       ...

  5. 浅析=======Struts2之==========valueStack

    今天刚学习了struts2的valueStack,在这里把自己学到的做个分享,说道valueStack就不得不提OGNL表达式=== struts2工作流程 1.OGNL(Object Graph N ...

  6. Struts2中ValueStack结构和总结

    [ValueStack和ActionContext的关系] 首先,从结构上来看ValueStack是ActionContext的一个组成部分,是对ActionContext功能的扩展.ActionCo ...

  7. -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

     本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法的区别 为什么wait( ...

  8. DFT,可测试性设计--概念理解

    工程会接触DFT.需要了解DFT知识,但不需要深入. 三种基本的测试(概念来自参考文档): 1. 边界扫描测试:Boundary Scan Test: 测试目标是IO-PAD,利用JTAG接口互连以方 ...

  9. 分享知识-快乐自己:初始 Struts2 (基本概念)及 搭建第一个Demo

    1):struts2 的基本概念: 1-1):Struts2 是什么? 1.Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2 ...

随机推荐

  1. (剑指Offer)面试题50:树中两个结点的最低公共祖先

    题目: 求树中两个结点的最低公共祖先 思路: 考虑一下几种情况: 1.该树为二叉搜索树 二叉搜索树是排序树,位于左子树点的结点都比父结点小,而位于右子树的结点都比父结点大,只需要从树的根结点开始和两个 ...

  2. ionic的加载功能

    下面是代码(黄色背景的是加载功能的代码): <html ng-app="ionicApp"> <head> <meta charset="u ...

  3. Appium(JAVA)Windows 7系统搭建及示例运行

    Appium(JAVA)Windows 7系统搭建及示例运行 分类: Appium 2014-11-14 17:44 4323人阅读 评论(2) 收藏 举报 1.搭建Android环境 http:// ...

  4. OFBiz:初始RequestHandler

    RequestHandler,可以称之为请求处理器,在ControlServlet.init()中初始化: public class ControlServlet extends HttpServle ...

  5. EL和自定义函数库

    问题:在数据显示的时候经常需要调用一些方法对需要显示的数据进行基本的处理,如: 数据过滤.求子串等操作.那么就需要使用EL表达式进行快速的函数调用. 引入HTMLFilter.java类 描述为函数 ...

  6. android多线程进度条

    多线程实现更新android进度条. 实例教程,详细信息我已经注释   android多线程进度条   01package com.shougao.hello; 02 03import android ...

  7. C#:ZedGraph画图控件(待补充)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  8. state Threads 开源库介绍

    译文在后面. State Threads for Internet Applications Introduction State Threads is an application library ...

  9. cocos2d-x-3.0创建项目

    之前一直用的是cocos2d-x-2.3版本号,使用tools里面的create-project.py脚本能够非常方便的创建项目.今天更新为3.0后,发现新版创建项目的方式有了非常大的改变,于是在这里 ...

  10. 使用多字节字符集的跨平台(PC、Android、IOS、WP)编码/解码方法

    随着移动端的发展,跨平台已成为通讯架构设计的重要考虑因素,PC.Android.IOS.WP等跨多平台间的数据通讯,必然要解决字符编码/解码的问题. 多字节字符集MBCS不是跨平台的首选字符集,面向跨 ...