您的位置:首页 > 编程语言 > Java开发

Struts2中的OGNL

2016-06-21 23:59 316 查看

根和上下文对象

框架设置 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 的内容先写到这里,其他的内容会在后面补充
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: