OGNL语法

8.1 OGNL语法

8.1.1 ActionContext、StackContext、ValueStack关系

ActionContext、StackContext、ValueStack对象与OGNL密切相关,理解三者之间的关系是掌握OGNL语法的根本。

1. ActionContext对象

ActionContext(com.opensymphony.xwork.ActionContext)是Action执行时的上下文,上下文可以看作是一个容器,它存放Action在执行时需要用到的对象,例如,请求的参数(Parameter)、会话(Session)、Servlet上下文(ServletContext)。在每次请求执行Action之前都会创建新的ActionContext。ActionContext是线程安全的,在同一个线程中ActionContext的属性是唯一的。值得注意的是ActionContext不仅保存了Action在执行时需要用到的数据,本身也可存放数据,例如以下代码用于将uid变量值保存到ActionContext对象中:

ActionContext.getContext().put("uid", "admin");

保存到ActionContext对象中的数据以后可通过Struts2标签和EL表达式语言进行访问。

2. StackContext 对象

Stack Context对象是ActionContext上下文中的一个java.util.Stack 实例。上述提及的请求参数(Parameter)、会话(Session)、Servlet上下文(ServletContext)等对象,实质是存储在ActionContext上下文中的StackContext对象中。

3. ValueStack对象

Struts2会为每一次Action的请求创建与之对应的ValueStack,并将所有Action属性数据存储到ValueStack中。再将ValueStack暴露给视图页面,这样页面就可直接访问后台处理生成的数据。

ActionContext、StackContext、ValueStack三者之间的关系如图1.8.1所示:

       

 

图 1.8.1 ActionContext、StackContext、ValueStack关系

 假设存在LoginAction控制器,代码如下:

public class LoginAction

{

private String uid;//封装用户名

private String pwd;//封装密码

public String execute() throws Exception

{

       //获取ActionContext对象  

ActionContext  ctx=ActionContext.getContext();

//将uid的值存储到session中

ctx.getSession().put("uid", this.uid);

        //将uid的值存储到Stack Context中

    ctx.put("uid", this.uid);

return "success";

}

//getter、setter代码省略…

}

并且已经正确将该Action的uid属性赋值为scott,pwd属性赋值为tiger。则ActionContext、StackContext、ValueStack三者此时的数据存放情况如图1.8.2所示:

 

图1.8.2   LoginAction数据存储情况

 

 

8.1.2 OGNL语法基础

OGNL是Object-Graph Navigation Language(对象图导航语言)的缩写,它是一种功能强大的表达式语言,通过它的简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。

1.访问OGNL上下文中的数据

ActionContext是Struts2中OGNL的上下文环境,也即向ActionContext中添加的数据(实际存储在Stack Context中)都可以被OGNL来访问,而ActionContext又包括request,session,ValueStack等这些对象,所以OGNL也可以访问存储在这些对象中的数据。

Value Stack(值栈)是OGNL的根,由于OGNL上下文中的根对象可以直接访问,所以通过OGNL访问Value Stack中的数据时不需要使用任何特殊的“标记”,而访问ActionConext中的其他对象则需要使用“#”标记。在Struts2中提供了<s:property>标签来访问OGNL上下文中的数据。

(1) <s:property value=”uid”/>

运行该标签时,Struts2会在Value Stack中去查找名为uid项,并输出其值

(2) <s:property value=”#uid”/>

运行该标签时,Struts2会在StackContext中去查找名为uid项,并输出其值

(3) <s:property value=”#session.uid”/>

运行该标签时,Struts2会在StackContext中的session作用域中去查找名为uid项,并输出其值。

(4) <s:property value=”#attr.uid”/>

运行该标签时,Struts2会依次在StackContext的page,request,session,application范围内查找对应的uid中的值。

2.访问JavaBean属性

假设存在employee对象作为OGNL上下文的根对象,对于下面的表达式:

(1) <s:property value=”name”/>

运行该标签时,Struts2会执行employee对象的getName()方法,对应的Java代码是:employee.getName()

(2) <s:property value=”address.country”/>

运行该标签时,Struts2会执行employee对象的getAddress()方法和getCountry()方法。对应的Java代码是:employee.getAddress().getCountry()

3.执行JavaBean方法

OGNL不仅可以自动执行getter方法,还能执行JavaBean的其它方法,更重要的是,在执行方法时,还能给方法传入参数。OGNL执行的方法或以静态方法或非静态方法。

执行静态方法的格式为:@类的全限名@方法名(参数),为了能让OGNL执行静态方法,必须在struts.xml文件中配置常量,以开启调用静态方法功能,配置代码如下:

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

以下示例演示了使用OGNL执行JavaBean方法:

(1) 创建一个JavaBean,命名为OgnlInfo.java,代码如下:

public class OgnlInfo {

//定义静态方法

public static String  sayBye(String name)

{

return name+"再见!";

}

//定义非静态方法

public String sayHello(String name)

{

return name+"你好!";

}

 }

(2) 创建index.jsp页面,代码如下:

  <body>

     <%

        //实例化ognl对象

        OgnlInfo ognlInfo=new OgnlInfo();

        //将ognlInfo对象存入request作用域内

        request.setAttribute("ognlInfo",ognlInfo);

      %>

     <!-- 执行ognl对象的非静态方法 -->

    <s:property value="#request.ognlInfo.sayHello('jack')"/>

     <!-- 执行ognl对象的静态方法 -->

<s:property value="@com.soft.struts8l.entity.OgnlInfo@sayBye('tom')"/>

  </body>

运行index.jsp页面,结果如图1.8.3所示:

 图1.8.3 OGNL执行JavaBean的方法

4.OGNL操作符号

OGNL表达式中能使用的操作符基本跟Java里的操作符一样,除了能使用 +, -, *, /, ==, !=, = 等操作符之外,还能使用 mod(取余), in, not in等

5. %符号

%符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值。以下示例代码用于演示%符号在OGNL中的使用方法。

  <body>

    <%

       String title="提交";

       pageContext.setAttribute("title",title);

     %>     

      不使用%符号,会按原样显示

      <s:submit value="#attr.title"/><hr>

      使用%符号,会计算OGNL表达式的值

      <s:submit value="%{#attr.title}"/>

   </body>

运行此示例,结果如图1.8.4 所示:

 

图1.8.4 OGNL %符号的用法

6. OGNL中的集合操作

 (1) 生成List类型集合

     {e1,e2,e3 . . . } 

     以上语法,直接生成一个List类型集合,该集合包含了3个元素:e1、e2和e3。如果需要更多元素,则多个元素之间以英文逗号隔开。

(2) 生成Map类型集合

     #{key1:value1,key2:value2,. . . }

    以上语法,直接生成一个Map类型集合,该Map中每个key-value对象之间以英文冒号隔开;多项之间以英文逗号隔开。

 (3) 使用in 和 not in 运算符

   对于集合,OGNL提供两上元素符:in和not in,其中in判断某个元素是否在指定集合中;not in则用于判断某个元素是否不在指定集合中。以下代码演示了in和not in的用法:

        <!-- 判断java是否在指定集合中 -->

     <s:if test=" 'java' in {'java','jsp','html'}">

         在里面

        <s:else>

                不在里面

           </s:else>

        </s:if>

 

(4) 获取集合的子集

    OGNL允许通过某个规则取得集合的子集。取得子集时有以下3种操作符:

    ?:取出所有符合选择逻辑的元素

    ^:取出符合选择逻辑的第一个元素

    $:取出符合选择逻辑的最后一个元素

    假定在session作用域中存在名为persons集合, 该集合由多个Person类的实例组成, 在Person类中存在一个age属性,用于描述年龄,则#session.persons.{? #this.age>20} 表达式用于取出年龄大于20的persons类子集合;#session.persons.{? ^this.age>20} 表达式用于取出第一个年龄大于20的Person类实例;#session.persons.{? ^this.age>20} 表达式用于取出最后一个年龄大于20的Person类实例。   

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值