玩技术,Geeker
一个原创技术文章分享网站

Struts2学习之OGNL表达式

OGNL是什么?

OGNL(Object Graphic Navigation Language,对象图导航语言)是一个开源的表达式引擎。通过使用OGNL的表达式语法可以存取Java对象树的任意属性和调用Java对象树的方法等。 Struts2框架就是使用OGNL作为默认的表达式语言。这就是OGNL。

ActionContext总结

要想把OGNL搞清楚了,比如OGNL到底是从哪里把值取出来的,以及又把值保存在哪里了。这些问题,必须要搞清楚OGNL的原理,你才能回答的到位。说到OGNL的原理,就必须要先说说ActionContext这个类,ActionContext表示的是Action的上下文环境,它封装了一个Action运行所需要的环境,比如session、parameters、locale等。如下图所示:

ActionContext

接下来的OGNL的操作都是基于ActionContext而进行的。对于这个ActionContext来说,每一个请求对应一个Action,所以说你不用担心什么线程安全的问题了。对于ActionContext中的SESSIONAPPLICATIONPARAMETERSLOCALE就不用多说了,我们重点总结的还是VALUE_STACK

ValueStack总结

这个VALUE_STACK是个什么东西呢?从名字上来看,它应该是个栈,先进后出的属性特点。ValueStack被称为值栈,是对OGNL的扩展,Struts2正式通过ValueStack来使用OGNL进行赋值和取值操作的。ValueStack内部封装了一个CompoundRoot类型的对象作为root属性,CompoundRoot是一个继承ArrayList的栈存储结构。而所有被压入栈中的对象,都会被视为OGNL的Root对象。在使用OGNL计算表达式时,首先会将栈顶元素作为Root对象,进行表达式匹配,匹配不成功则会依次向下匹配,最后返回第一个成功匹配的表达式计算结果。因此,Struts2通过ValueStack实现了多Root对象的OGNL操作。

当你提交一个请求,会为这个请求创建一个和web容器交互的ActionContext,与此同时会创建ValueStack,并置于ActionContext之中。而实例化Action之后,就会将这个action对象压入ValueStack中。在请求“映射”过程中,Struts2则是通过ParametersInterceptor拦截器将提交的参数值封装入对应的Action属性中。因此action实例可以作为OGNL的Root对象,对于Action中的属性、方法都可以使用OGNL来获取。

OGNL的基本操作

说了这么多,现在来看看到底如何真正的使用OGNL。

  • 访问ValueStack
    由于ValueStack是Struts2中OGNL的根对象,如果用户需要访问值栈中的对象,在JSP页面可以直接通过下面的OGNL表达式访问ValueStack(值栈)中对象的属性:

    <s:property value="userName" />
    

    在ValueStack中处于第一位的对象叫栈顶对象。通常我们在OGNL表达式里直接写上属性的名称即可访问ValueStack变量里对象的属性,搜索顺序是从栈顶对象开始寻找,如果栈顶对象不存在该属性,就会从第二个对象寻找,如果没有找到就从第三个对象寻找,依次往下访问,直到找到为止。

  • 访问application对象
    访问ValueStack以外其它对象时,由于他们不是根对象,所以在访问时,需要添加#前缀。application对象用于访问ServletContext的属性,例如:

    <s:property value="#application.userName" />
    <s:property value="#application['userName']" />
    

    上述代码同调用ServletContextgetAttribute("userName")方法的效果是一样的。

  • 访问session对象
    session对象用于访问HttpSession的属性,例如:

    <s:property value="#session.userName" />
    <s:property value="#session['userName']" />
    

    上述代码同调用HttpSessiongetAttribute("userName")方法的效果是一样的。

  • 访问request对象
    request对象用于访问HttpServletRequest的属性,例如:

    <s:property value="#request.userName" />
    <s:property value="#request['userName']" />
    

    上述代码同调用HttpServletRequestgetAttribute("userName")方法的效果是一样的。

  • 访问parameters对象
    parameters对象用于访问HTTP请求参数,例如:

    <s:property value="#parameters.userName" />
    <s:property value="#parameters['userName']" />
    

    上述代码同调用HttpServletRequestgetParameter("userName")方法的效果是一样的。

  • 访问attr对象
    attr对象依次搜索以下对象中的属性,找到便返回:

    1. PageContext
    2. HttpServletRequest
    3. HttpSession
    4. ServletContext

OGNL集合操作

很多时候,我们都会需要一个集合对象,使用OGNL表达式可以直接创建集合对象。

创建List的语法为:

{value1, value2, value3}

创建Map的语法为:

#{key1:value1,key2:value2,key3:value3}

具体的使用示例代码如下:

<!-- 创建一个List -->
<s:set name="varList" value="{'www.google.com','www.facebook.com','www.jellythink.com'}" />
<s:iterator value="#varList" id="n">
    <s:property value="n"/><br>
</s:iterator>

<!-- 创建一个Map -->
<s:set name="varMap" value="#{'谷歌':'www.jellythink.com', '脸书':'www.facebook.com', '果冻想':'www.jellythink.com'}" />
<s:iterator value="#varMap" >
    <s:property value="key"/>=<s:property value="value"/><br>
</s:iterator>

<s:set .../>标签用于将某个值放入指定范围,它可以指定以下两个属性:

  • scope:指定变量被放置的范围,该属性可以接受application、session、request、 page或action。如果没有设置该属性,则默认放置在OGNL Stack Context中。
  • value:赋给变量的值.如果没有设置该属性,则将ValueStack栈顶的值赋给变量。

对于集合,OGNL还提供了以下两个运算符:

  • in运算符,判断某个元素是否在集合中
  • not in运算符,判断某个元素是否不在集合中

示例代码如下:

<s:if test="100 in {100,200,300}">
   包含
</s:if>
<s:else>
   不包含
</s:else>

OGNL访问静态成员

在开发中,避免不了要访问静态变量和静态方法。为此,OGNL表达式还提供了一种访问静态成员的方式,但Struts2默认是关闭访问静态方法的,只允许通过OGNL表达式访问静态变量。为了让OGNL表达式可以访问静态方法,需要在Struts2配置文件中添加如下配置:

<constant name="struts.ognl.allowStaticMethodAccess" value="true" />

为了方便测试,在Action中添加以下几行代码:

public static String strWebSite = "http://www.jellythink.com";

public static String getStrWebSite()
{
    return "果冻想 - " + strWebSite;
}

在JSP页面中,我们就可以这样进行访问了:

<s:property value="@com.jellythink.practise.LoginAction@strWebSite" />
<s:property value="@com.jellythink.practise.LoginAction@getStrWebSite()" />

是的,做起来就是这么简单,没什么!

总结

这篇文章就总结到这里了,的确花费了一点时间来总结这篇文章,对于那些不熟悉的地方,都要去写DEMO进行一一验证。好了,下一篇再见~~~

果冻想-一个原创技术文章分享网站。

2016年2月27日 于呼和浩特。

打赏

未经允许不得转载:果冻想 » Struts2学习之OGNL表达式

分享到:更多 ()

评论 6

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #4

    不错不错,谢谢分享

    天下彩12个月前 (10-13)回复
  2. #3

    新年好啊~

    cloudxiao9个月前 (01-03)回复
  3. #2

    来访,支持下

    孵化器8个月前 (02-08)回复
  4. #1

    学到了,可以交换链接吗?http://www.makingh.com/

    小恒6个月前 (03-31)回复

在这里玩技术,享受技术带来的疯狂

捐赠名单关于果冻