struts与ognl结合【重要】

-----------------------------ognl表达式------------------------

OGNL:对象视图导航语言.  ${user.addr.name} 这种写法就叫对象视图导航.
OGNL不仅仅可以视图导航.支持比EL表达式更加丰富的功能.

 

1.使用OGNL准备工作

1.1  导包

  struts2 的包中已经包含了.所以不需要导入额外的jar包

1.2  代码准备

 

1.3  语法

  1.3.1  基本取值

 

  1.3.2  复值

  1.3.3  调用方法

  1.3.4  调用静态方法

  1.3.5  创建对象list,map

----------Ognl与Struts结合---------------------------------

2.结合原理

2.1栈原理

 

 

栈中的两个方法的实现

2.2  查看值栈中两部分内容(使用DEBUG标签)

方法:

<%@ taglib uri="/struts-tags" prefix="s" %>
...
<s:debug></s:debug>

2.2.1  root

 

默认情况下,栈中放置当前访问的Action对象以及Action的带有getter方法的属性。

 

2.2.2  Context

默认情况下,存放是数据中心,request、session,application,actionMapping....等

 

Context部分就是ActionContext数据中心

2.3  struts2与ognl结合体现

2.3.1  参数接收

 

 

 

2.3.2  配置文件中

语法:${ognl表达式}

2.4  扩展:request对象的getAttribute方法

查找顺序

 

---------------Struts2 中的值栈的理解-----------------------------

通过对struts2的一段时间的接触,将自己对OGNL的核心值栈说说, 值栈:简单的说,就是存放action的堆栈,当我们提交一个请求道服务器端 action时,就有个堆栈,如果action在服务器端进行跳转,所有action共用一个堆栈,当需要保存在action中的数据时,首先从栈顶开始 搜索,若找到相同的属性名(与要获得的数据的属性名相同)时,即将值取出,但这种情况可能出现找到的值不是我们想要的值,那么解决此问题需要用TOP语法 和N语法来进行解决。 



    当在客服端进行跳转时,当有请求提交到服务器的action时,只有一个堆栈存在,堆栈中存放的是当前的请求的action,而原来那么则销毁了(本人观 点,感觉如同request请求一样)。 

****************************************************** 
众 所周知,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类的相应属性 

 众所周知,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类的相应属性

 

------------------------------------操作值栈--------------------

1.在action类中对值栈的操作

     操作Map:  ActionContext.getContext()

 

                       .put(k, v)

                       .get(k)  

                      或者

                       .put(k, v)

                       .get(k)

 

ActionContext.getContext.getValueStack()

                          .push(obj)

        .pop()

2.在Result中操作值栈(大多在jsp文件中的操作)

 通过使用OGNL表达式操作值栈

格式     

   struts.xml中,格式如${ognl}

       Jsp文件中,格式如%{ognl},而且必须写在struts2的自定义标签的属性中,在外面不会被解析

语法

  

 

findValue()的查找顺序:

        ①从对象栈的栈顶开始查找对象的属性,找到返回

        ②如果对象栈中找不到,进Map查找对应key,返回value,找到返回

    

例子:                  

<span style="font-size:18px;background-color: rgb(255, 255, 255);"><s:iterator value="#roleList">  
    <s:property value="id"/>,  
    <s:property value="name"/>,  
    <s:property value="description"/>,  
    <s:a action="role_delete?id=%{id}" onclick="return confirm('确定要删除吗?')">删除</s:a>  
    <s:a action="role_editUI?id=%{id}">修改</s:a>  
    <br/>  
</s:iterator></span> 

 

    在值栈的Map里面有roleList的List,取出来循环

    循环标签还有个特定的功能,循环一次开始后,会把对象拿到栈顶,因此id,name,dedcription会取到当前对象的属性,这里的“%{}”可以省略。

 

EL表达式可以使用值栈吗?

       EL表达式原本的查找顺序为:

    page,request,session,application,找到返回。

但是

    struts2对request对象进行了增强,即StrutsRequestWrapper对象,里面重写了getAttribute()方法:在request找不到之后到值栈里面找,EL表达式的查找顺序变为:page,request,valueStack.findValue(),session,application。

所以上述例子也可以写为:

  <s:iterator value="#roleList">  

        ${id},  
        ${name},  
        ${description},  
        <s:a action="role_delete?id=%{id}" onclick="return confirm('确定要删除吗?')">删除</s:a>  
        <s:a action="role_editUI?id=%{id}">修改</s:a>  
        <br/>  
    </s:iterator> 

 


 

 

 

posted @ 2017-08-21 19:04  QiaoZhi  阅读(293)  评论(0编辑  收藏  举报