Struts2中的OGNL

来源:互联网 发布:淘宝太阳能铝塑管 编辑:程序博客网 时间:2024/06/05 19:24

根和上下文对象

框架设置 OGNL上下文对象为ActionContext, value stack是OGNL的根对象. ( value stack 包含多个对象, 但是对OGNL来说就好像是一个
对象)。和 value stack一起,框架把其他对象放置到 ActionContext中, 包括代表application, session和request 上下文的map.这些对
象和value stack ( OGNL根)放置在 ActionContext .
我们通过看ActionContext源码我们发现类中的context属性是作为上下文的map的
这里写图片描述
这里写图片描述

OgnlContext ognlMap =   (OgnlContext) ActionContext.getContext().getContextMap();

这里是一张关系图:
这里写图片描述
通过查看源代码我们能很轻易的找出它们之间的关系

我们在一个action类中的ex方法写测试代码

@Override    public String execute() throws Exception {        OgnlContext ognlMap =   (OgnlContext) ActionContext.getContext().getContextMap();        ognlMap.put("test01", "这是测试01");        //以上方法获取OgnlContext 比较麻烦         //我们通常才用下面的方式        ActionContext.getContext().put("test02", "这时测试02");        messageStore = new MessageStore();        helloCount++;        return SUCCESS;    }

jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>    <%@taglib uri="/struts-tags" prefix="s" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><h2><s:property value="messageStore.message"/></h2><br><p>I've watched <s:property value="helloCount"/> times</p><p> 上下文中 test01 的值  <s:property value="#test01"/> </p><br><p> 上下文中 test02 的值  <s:property value="#test02"/> </p><br></body></html>

这里写图片描述
我们会发现两种方式都可以把数据插入到上下文中
ValueStack:是Struts2中OGNL的根对象,它是一个栈
我们创建一个对象放到值栈中:

MessageStore ms01 = new MessageStore();        ms01.setMessage("第一条  message ");        ActionContext.getContext().getValueStack().push(ms01);

jsp代码:

<p>从值栈message </p><s:property value="messageStore.message"/>

这里写图片描述
如果我们这时后在创建一个MessageStore对象并放到值栈中会怎么样呢?

        MessageStore ms01 = new MessageStore();        ms01.setMessage("第一条  message ");        ActionContext.getContext().getValueStack().push(ms01);        MessageStore ms02 = new MessageStore();        ms02.setMessage("第二条  message ");        ActionContext.getContext().getValueStack().push(ms02);

这里写图片描述
我们看到jsp页面没发生变化时 ,输出的值变成了 新添加ms02的值了
到这里我们就要详细的说一下上下文和根了
我们看一下ValueStack和其实现类之间的关系类图:
这里写图片描述
ValueStack是一个接口,在struts2中使用OGNL表达式实际上是使用实现了ValueStack接口的类OgnlValueStack,这个类是OgnlValueStack的基础。
ValueStack贯穿整个action的生命周期。每一个action实例都拥有一个ValueStack对象。其中保存了当前action对象和其他相关对象。
在jsp 页面上使用 struts2的 标签,我们可以在页面上看到上下文和值栈中的值:
这里写图片描述
以下是值栈中的数据:
这里写图片描述
我们注意到:上面有两个MessageStore 对象 ,分别是我们保存进去的ms1和ms2我们是通过:

<s:property value="message"/>

找到值的,上面说的ValueStack是OGNL的根对象,但是ValueStack有getMessage()方法吗?没有 ,说明 上面代码执行时,根对象并不是ValueStack,通过上面的图,我们可以判断出是MessageStore 对象作为OGNL的根,那么问题来了,上面有两个MessageStore 对象,到低哪个作为根呢,这有回到了ValueStack上面了,我们说他是值栈,作为栈,其中的元素是怎么保存的呢?
栈具有先进后出的特点,保存时元素从栈顶进去,取出时,同样从栈顶取出,ValueStack作为OGNL的值栈,就是这样的,也就是说时ValueStack栈中的元素作为根对象的,由于栈的特点,先进的后出,所以我们查询某个属性时,如果不写#,就从栈中找,它会首先从上图的第一个对象做为根 ,如果该对象没有此属性的话,就把下一个元素做根,继续找,直到找到为止,如果都没有,则什么也不输出,
那么我们能不能访问到此例中ms1对象的message呢?
可以,在jsp页面上写上

<br><p>从栈的第几个元素开始到栈底部 找 </p><s:property value="#root[1].message"/>

其中#代表从上下文中找,值栈也是存在上下文中的,其键名 root ,
root[i] ,表示从下标i开始截取到最后,返回值作为新的值栈
这里写图片描述
root[1]并不是说返回值栈中的第二个元素,而是返回的一个新的值栈
访问OGNL上下文和Action上下文,#相当于ActionContext.getContext();下表有几个ActionContext中有用的属性:
这里写图片描述
这里写图片描述
struts2向上下文中对象放置的对象:
1 request是Map
存放request范围变量
2 session是Map
存放会话范围变量
3 application是map
存放application变量

4 attr放置request,session和application范围的变量
首先到request>session>application找
5 action放置的你请求Action类
6 parameters是Map
它里面放置的是请求参数,参数值是数组类型,访问例子:

接下来我们就写代码测试

         // 耦合法(调用Servlet的API)        ServletActionContext.getRequest().setAttribute("reqAttr", "request 范围数据");        ServletActionContext.getRequest().getSession().setAttribute("sessAttr", "session 范围数据");        //解耦合(没有调用Servlet相关API)        ActionContext.getContext().getApplication().put("applicaAttr", "application 范围数据");        // 测试 attr           ActionContext.getContext().getSession().put("r", "sessionxxx");        ActionContext.getContext().getApplication().put("r", "requestxxxxxxxxxxxx");

这里写图片描述
测试 parameters

<p>parameters 保存 请求参数  每个参数 是一个数组  是一个map 保存在 上下文中</p> 第一个name : <s:property value="#parameters['name'][0]"/><br> 第二个name : <s:property value="#parameters['name'][1]"/>

这里写图片描述
OGNL 调用对象非静态方法

<br><p>调用对象非静态方法</p><s:property value="messageStore.show()"/>
我是非静态方法 

调用共有静态方法:
要使在前台能够顺利的调用后台的公共静态方法,还需要在Struts的配置文件里面申明可以在前台调用后来的静态方法

<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>  
<s:property value="@com.lgh.struts2maven.model.MessageStore@staticTest()"/>
我是静态方法

OGNL 调用构造方法

<s:property value="new com.lgh.struts2maven.model.MessageStore().message"/>
Hello , Java Struts2 

OGNL 的内容先写到这里,其他的内容会在后面补充

0 0