OGNL表达式原理及使用

OGNL :object graph navigation language,对象图形导航语言,一种表达式语言。


为什么出现:


        在我们所熟悉的mvc框架中,数据是在各层之间进行流转使用的。
        显示层:将数据展示给用户,数据不分类型,统一按照字符串处理
        后台:处理数据,在java中数据分为很多类型,我们可以自行定义。

        这样在页面和java中数据的传递使用就会出现不匹配的问题。数据不匹配的问题还在java程序和数据库之间存在,ORM框架可以解决这个问题,我们使用过EF,hibernate等。OGNL就是为了解决java和页面之间数据不匹配而产生的。

原理:


        OGNL表达式能够在jsp页面上直接通过表达式进行java后台的数据显示主要依赖于值栈。值栈中的数据结构包括两种:对象栈和map栈,其中对象栈是list而map栈就同名字一样是map。


 


        上图中:整个蓝色的为valuestack,橘色为OGNLContext,绿色为root对象栈。从图中可以看出OGNLContext包含了map栈和对象栈。这样存在两份对象栈方便使用。这个蓝色值栈的生命周期是客户发起的一次请求。


赋值:


        使用OGNL表达式在jsp页面上回显java后台返回的值,OGNL是从valuestack中取的数据,而valuestack中的数据则是在java后台存入的。那么valuestack中的值的java中是如何存入的呢?首先看两行代码

//得到整个的ognl的context包含了对象栈和map栈。
ActionContext.getContext().getValueStack().getContext();

//只得到对象栈。
ActionContext.getContext().getValueStack().getRoot();

       上两行代码可以获取到map栈和对象栈,获取之后我们可以开始对象栈或map栈中添加我们准备好的数据。


       怎么样把一个数据放入到对象栈中

//把departmentList放入到了对象栈的栈顶
ActionContext.getContext().getValueStack().getRoot().add(0, departmentList);
ActionContext.getContext().getValueStack().push(departmentList); //push()方法是对.getRoot().add()方法的封装		

//把departmentList放入到了对象栈的栈底
ActionContext.getContext().getValueStack().getRoot().add(departmentList);

//获取对象栈的栈顶的元素
ActionContext.getContext().getValueStack().getRoot().get(0);
ActionContext.getContext().getValueStack().peek();//peek()方法是对.getRoot().get()方法的进一步封装

//移除对象栈的栈顶的元素
ActionContext.getContext().getValueStack().getRoot().remove(0);
ActionContext.getContext().getValueStack().pop();//pop()方法是对.getRoot().remove()方法的进一步封装


        对象栈的说明:
              1、处于对象栈的对象中的属性是可以直接访问的
              2、如果在对象栈中有一样名称的属性,从栈顶开始查找,直到找到为止
              3、一般情况下,回显的数据应该放在对象栈中,这样效果比较高
              4、用ognl表达式访问对象栈,直接属性名称就可以了,不用加#



        怎么样把一个数据放入到map栈中
//把一个对象存放到map栈中
ActionContext.getContext().put("departmentList", departmentList);

//对象放到map中的request中
ServletActionContext.getRequest().setAttribute("departmentList", departmentList);//OGNL表达式中的使用 #request. departmentList.属性名

        Map栈说明
               1、reuqest,session,application都在map栈中
               2、可以把一个对象放入到map中
               3、ognl表达式访问map栈中的内容
                         如果一个对象在request中
                                #request.对象的key值.属性
                         如果一个对象直接放入到map中
                                #对象的key值.属性
                4、把一个对象放入到map栈中,是不能直接访问该对象的属性


使用:


        Valuestack中存放数据后在jsp页面中使用OGNL表达式获取值一般使用三种符号#,%,$。


        对象栈中数据使用:不需要任何的符号,直接使用属性名。

               后台赋值——
public String textValueStack() throws Exception {
	User user =new User();
	user.setName("test");
	user.setPassword("123");
	ActionContext.getContext().getValueStack().push(user);
}

                       Jsp页面使用——
<s:property value="name"/>
<s:property value="password"/>


              页面显示——

                         

        Map栈中的数据使用:需要使用#号

              可以直接在jsp页面中构建一个map,代码——

<s:set name="myMap" value="#{'key1':'name','key2':'password'}"/>      
使用property标签:<s:property value="#myMap['key1']"/>      
 <br/>
使用非property标签:<br/>
————url:<s:url value="#myMap['key1']" />    <br/> 
————label:<s:label value="#myMap['key1']"></s:label>

               页面显示效果——

                        

 

       从效果图中看出使用#号获取map中的值使用property的标签没有问题,使用其他类型标签表达式被当做是字符串显示了。出现这种情况就需要使用到%,所以OGNL表达式中的%是用来标记的。


             代码——
<s:set name="myMap" value="#{'key1':'name','key2':'password'}"/>      
使用property标签:<s:property value="#myMap['key1']"/>      
 <br/>
使用非property标签:<br/>
————url使用%{}进行标记:<s:url value="%{#myMap['key1']}" />    <br/> 
————label:<s:label value="#myMap['key1']"></s:label>

               页面显示效果——
                       


        OGNL表达式中$和我们熟知的el表达式的符号是相同的,所以OGNL表达式的$用在其他地方——

               (1)、在国际化资源文件中,引用OGNL表达式。   

               (2)、在Struts 2配置文件中,引用OGNL表达式。


小结:
        OGNL表达式需要struts2标签的支持,EL表达式则需要jstl库的支持。
        OGNL表达式是从valuestack中获取数据,EL表达式是从jsp的内置对象pageContext、request、session、application中依次查找属性值返回的。
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 23
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值