`

struts2中的ValueStack学习

阅读更多
在 JSP 中,使用 struts2 的 <s:debug/> 标签,可以将 Value Stack 中的内容打印在 JSP 页面上展现出来。


理解ValueStack的基本机制


ValueStack基础:OGNL(Object Graphic Navigation Language)

OGNL是Struts2中使用的一种表达式语言。它可以用于:
  · 在JSP页面,使用标签方便的访问各种对象的属性;
  · 在Action中获取传递过来的页面中的参数(并进行类型转换);
  · 可以用在struts2的配置文件中!
所以,非常有必要理解OGNL的基本机制。


Root对象

OGNL称为对象图导航语言。
所谓对象图,即以任意一个对象为根,通过OGNL可以访问与这个对象关联的其它对象。
OGNL不支持多个root对象。

如:

package cn.com.leadfar.struts2.actions;
public class User {

    private String username;
    private Group group;

    public String getUsername() {
       return username;
    }
    public void setUsername(String username) {
       this.username = username;
    }
    public Group getGroup() {
       return group;
    }
    public void setGroup(Group group) {
       this.group = group;
    }

}

package cn.com.leadfar.struts2.actions;
public class Group {

    private String name;
    private Organization org;

    public String getName() {
       return name;
    }
    public void setName(String name) {
       this.name = name;
    }
    public Organization getOrg() {
       return org;
    }
    public void setOrg(Organization org) {
       this.org = org;
    }
}

 
package cn.com.leadfar.struts2.actions;
public class Organization {

    private String orgId; 

    public String getOrgId() {
       return orgId;
    }
    public void setOrgId(String orgId) {
       this.orgId = orgId;
    }
}


上面三个类,描述了通过一个User对象,可以导航到Group对象,
进而导航到Organization对象。
以User对象为根,一个对象图如下所示:

User(root)

   -- username
   -- group
      -- name
      -- org
         -- orgId



在真实的环境下,这个对象图可能会极其复杂,但是通过基本的getters方法,都应该能够访问到某个对象的其它关联对象。
【对象图的导航,必须通过getters方法进行导航】
下述代码将创建一个User对象,及其相关的一系列对象:

       User user = new User();
       Group g = new Group();
       Organization o = new Organization();
       
       o.setOrgId("ORGID");
       g.setOrg(o);
       user.setGroup(g);


如果通过JAVA代码来进行导航(依赖于getters方法),导航到Organization的orgId属性,如下所示:

//用JAVA来导航访问
user.getGroup().getOrg().getOrgId();


【注意:导航的目的,是为了获取某个对象的值或设置某个对象的值或调用某个对象的方法!】
【注意:OGNL表达式语言的真正目的,是为了在那些不能写JAVA代码的地方执行JAVA代码,或者是为了更方便地执行JAVA代码】
利用OGNL进行导航的代码如下:

       //利用OGNL表达式访问
       String value = (String)Ognl.getValue("group.org.orgId", user); 


Ognl.getValue()方法的第一个参数,就是一条OGNL表达式,第二个参数是指定在表达式中需要用到的root对象!



详细请参考官方的文档
https://struts.apache.org/docs/ognl.html

__________________________________

言归正传
__________________________________


ValueStack

Struts2是通过ValueStack来进行赋值与取值的。
ValueStack实际上就是对OGNL的封装,OGNL主要的功能就是赋值与取值。

ValueStack中的数据,分两个部分存放:root和context
同时ValueStack暴露相关的接口(赋值和取值):
void setValue(String expr, Object value);
Object findValue(String expr);
通过OGNL表达式对ValueStack中的数据进行操作。

root

ValueStack中的root对象是CompoundRoot。
CompoundRoot继承了ArraryList,提供了额外的方法:push()和pop()方法,
用来对root对象中所包含的数据进行存取。
正是通过这两个方法,CompoundRoot变成了一个栈结构.
压栈操作,将导致对象被放到CompoundRoot的第0个元素上(第0个元素是栈顶),其它对象被依次往后移动;
出栈操作,将导致CompoundRoot的第0个元素被移除(即栈顶元素被弹出),其它对象被依次往前移动

OGNL只能访问被压入堆栈(CompoundRoot)中的元素。
在Struts2中,一个请求在最终到达Action的方法之前,Action对象本身会被压入
ValueStack的CompoundRoot对象中。
所以Action对象是CompoundRoot对象中的一个元素,可以使用OGNL表达式直接访问。

在jSP页面中,使用<s:property value=”ognl表达式”/>标签,将CompoundRoot栈中的值取出。
在<s:property>标签中的OGNL表达式,最终会交给ValueStack来解释。
比如:"username"就是一个OGNL表达式,意思是调用root对象的getUsername()方法。



Context


由于在OGNL中,不支持多个root对象,但在struts2的OGNL的表达式中,
有可能需要访问到多个毫不相干的对象。这时候,我们把表达式中需要用到的对象放到Map中,
传递给OGNL,进行访问。这个Map对象,称为context。

可见valueStack对OGNL进行了扩展,使OGNL表达式可以访问到多个root对象。

要在表达式中访问到context中的对象,需要使用“#对象名称”的语法规则。
#表示将context对象的元素放入到CompoundRoot对象的栈顶。访问完后,
context对象的元素会从栈顶移出,自动释放。

当CompoundRoot栈中存在多个不相干的root对象时,使用 #root[n]. 进行访问,
n是root对象当前在栈中的顺序。从0开始。

请看下面的例子:

public class UserAction {

    private String username;

    //查看用户的详细信息
    public String detail(){

       username = "张三";      

       List list = new ArrayList();
       for(int i=0; i<10; i++){
           User user = new User();
           user.setUsername("User"+i);
           list.add(user);
       }

       ActionContext.getContext().put("users", list);      

       User u = new User();
       u.setUsername("赵毅");
       ActionContext.getContext().getValueStack().push(u);      

       return "detail";
    }
 


对应的JSP如下:

行1:  <s:property value="username"/> <br/>
行2:  <s:iterator value="#users">
行3:     <s:property value="username"/>
行4:     <s:property value="#root[2].username"/><br/>
行5:  </s:iterator>
行6:  <s:property value="username"/>
行7:  <s:property value="#root[1].username"/> <!-- 张三 -->


根据刚才的示例,我们知道,第1行的username是“赵毅”(因为JSP在执行这行代码的时候,CompoundRoot中有两个元素:第0个是“user对象赵毅”,第1个是“userAction对象张三”),因此第1行的username将取出CompoundRoot中第0个元素的username属性:赵毅

第2行代码是iterator标签,只定义了一个value属性,iterator标签将循环访问users这个List中的User对象,并把当前循环的user对象压入到CompoundRoot中!所以,在第3行和第4行代码被执行的时候,CompoundRoot中总共有3个元素:第0个元素是被iterator标签压入的当前循环的user对象;第1个元素是“user对象赵毅”;第2个元素是“userAction对象张三”,因此第3行代码的执行结果就是输出“UserX”,即当前循环的user对象的username属性!iterator标签将会依次取出List中的user对象,并不断压入/弹出user对象(每次循环,都将执行一遍压入/弹出)。而第4行代码取第2个元素的username属性,即userAction对象的username属性:张三。

第5行代码执行完成之后,在CompoundRoot中将剩下2个元素,与第2行代码被执行之前一样。所以,第6行代码的输出和第1行代码的输出结果是一样的,而第7行代码将取出userAction对象的username属性:张三


本文参考:

http://blog.sina.com.cn/s/blog_566be38401016jfp.html



-引用请注明
原文出处:http://lixh1986.iteye.com/blog/1739254











-
分享到:
评论
1 楼 kangwen23 2013-07-23  
谢谢了,顶顶

相关推荐

    Struts2中关于ValueStack的一些操作

    1、 ValueStack其实就是一个放置Java对象的堆栈而已,唯一特别的是可以使用EL来获得值堆栈中对象属性的数据,并可以为值堆栈的对象属性赋值。 2、 EL,全称Express Language,即表达式语言。不要被语言吓倒,它是...

    Struts中的ognl和valueStack

    深入讲解Struts中的ognl和valueStack

    Struts2中的参数传递

    我们知道,Struts2完成参数传递处理工作的基础是OGNL和ValueStack。而在这个 过程中,我也把Struts2所要做的工作大致归纳为两个方面: 1. 对OGNL操作进行封装,完成OGNL表达式所表示的值到Java对象的值传递机制 2. ...

    struts2 学习例子

    Struts2的标签库有一个巨大的改进之处,struts2标签库的标签不依赖于任何表现层技术,也就是说strtus2提供了大部分标签,可以在各种表现技术中使用。包括最常用的jsp页面,也可以说Velocity和FreeMarker等模板技术...

    马士兵Struts2笔记2013

    建立一个Struts2 工程,用Action的属性接收参数,使用Domain Model (实体模型) 接收参数,Struts2_2.1.6版本的中文问题,Struts模块包含,Struts简单数据验证 ,Struts ValueStack(值栈) Debug,Value Stack ...

    Struts2 in action中文版

    6.7.2 Struts 2中常用的表达式语言特性 131 6.7.3 表达式语言的高级特性 135 6.8 小结 137 第7章 UI组件标签 139 7.1 为什么需要UI组件标签 139 7.2 标签、模板和主题 144 7.2.1 标签 146 7.2.2 模板 146 7.2.3 ...

    Struts2入门教程(全新完整版)

    十二、总结 本教程对struts2的基本知识进行了一些说明,关于struts2的更多详细内容应参看struts2的官方文档及提供的app实例。 下面对struts2的基本执行流程作一简要说明,此流程说明可以结合官方提供的struts2结构图...

    Struts用的ognl和valueStack(vs)实例

    Struts用的ognl和valueStack(vs)实例

    Struts2 Value Stack Contents 中取值、多个集合数组

    Struts2 Value Stack Contents 中取值、多个集合数组示例

    struts2 标签库使用文档

    Struts2标签库的组成 ...数据访问标签:主要包含用于输出值栈(ValueStack)中的值,完成国际化等功能的标签。 流程控制标签:主要包含用于实现分支,循环等流程控制的标签。 AJAX标签:用于支持Ajax效果

    在线培训:ValueStack

    培训主要学习以下几个知识点: 1、制作PPT,讲解栈的特点和使用方法 2、编码实现回文对 3、制作PPT,讲解Struts2中的ValueStack 4、编码改变ValueStack中的对象的顺序

    Struts2练习Demo以及随笔

    Struts的开发步骤、OGNL、ValueStack、Action核心、Result基本原理、Struts2核心标记库、Struts2拦截器、自定义拦截器、UI标记、非UI标记、资源文件国际化等等实例全面使用。

    linjin101#javaStudy#Struts2中的OGNL和值栈ValueStack1

    1、什么是值栈 2、值栈的内部结构 3、ActionContext和ValueStatck的关系 4、如何获取值栈对象 5、向值栈存数据 6、从值栈中获取数据

    struts学习笔记(3)

    向页面传值可以使用struts2中特有的两个类的对象 com.opensymphony.xwork2.ActionContext和com.opensymphony.xwork2.util.ValueStack 1)ValueStack和ActionContext的作用: 当客户端向action发送请求并且最后跳转...

    Struts2基础教程

    讲解Struts2入门基础,包括Action、Result、ValueStack等,Struts2初学者会有帮助

    Struts2框架基础 二

    OGNL表达式 interceptor拦截器 valuestack的存入 /取出

    struts2模拟

    struts2模拟模拟工具,可以实现action访问,我表单属性的自动封装。提供了页面显示和跌带器,利用struts2值栈(valueStack)和对象栈map栈的思想。可以用来了解struts2的执行过程,纯属个人学习

    struts2的值栈

    用一个小小的flash来形象的演示struts2中值栈的操作过程,非常直观!

    ValueStack使用参考

    ValueStack的使用方法和一些技能

Global site tag (gtag.js) - Google Analytics