ognl

ognl:
对象图导航语言,表达式;el表达式:获取域对象中的值。
在Struts2中主要用来获取值栈中的内容。ognl不是Struts2中的一部分,它是完全独立存在的,如果想使用ognl需要导入ognl的jar包。

实现功能:
    1、支持对象方法调用,如xxx.doSomeSpecial();
    2、支持类静态的方法调用和值访问,表达式的格式:
       @[类全名(包括包路径)]@[方法名 | ?值名],例如:
       @java.lang.String@format('foo %s', 'bar')
       或@tutorial.MyConstant@APP_NAME;
静态类方法调用时需要进行常量的设置:<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
    3、访问OGNL上下文(OGNL context)和ActionContext;
    4、支持赋值操作和表达式串联,如price=100, discount=0.8,
  calculatePrice(),这个表达式会返回80;
    5、操作集合对象。

值栈:数据的一个中转站。
servlet和action的区别:
servlet:在第一次访问的时候创建一次,只有一个实例(线程安全)。
action:在访问的时候创建,每次访问都要创建新的action实例,每个实例里面都有一个值栈对象:valueStack。

值栈保存位置:
1)、在action中;2)、在request域中:request.setAttribute("struts.valueStack",valueStack);

获取值栈:
1)、域对象:
 ValueStack valueStack = (ValueStack)ServletActionContext.getRequest().getAttribute("struts.valueStack"); 
 ValueStack valueStack2 = ActionContext.getContext().getValueStack();

值栈结构:
  有两部分组成
 (1)root -- list集合
 数据默认存在root里面
 (2)context -- map集合
 root引用
 三个域对象
 attr
 parameters
 (3)采用栈:后进先出
 (4)获取值栈的context里面使用ognl时候添加#

向ognl中设置值:
1)、valueStack.set("key","value");2)、valueStack.put("value");
获取域对象、集合中的值:
request:<s:property value="#request.username"/>
session:<s:property value="#session.username"/>
application:<s:property value="#application.username"/>
attr:<s:property value="#attr.username"/>
parameters:<s:property value="#parameters.cid"/>
<s:property value="#request.list[1].username"/>
<s:property value="#request.list[1].password"/>

为什么el能获取值栈内容:
(1)增强request里面getAttribute方法
(2)在这个方法中,从域对象里面获取值,如果得不到,从值栈里面获取值,放到域对象里面

ognl的使用:
#号的使用:
 (1)#获取是值栈context内容
 用法一  # 获取context的数据
 request:<s:property value="#request.username"/>
 session:<s:property value="#session.username"/>
 application:<s:property value="#application.username"/>
 attr:<s:property value="#attr.username"/>
 parameters:<s:property value="#parameters.cid"/>

 用法二  条件的判断(进行投影映射)
 (2)使用struts2的标签 <s:iterator>:遍历集合内容,类似与jstl里面 forEach标签
 (3)使用iterator标签遍历值栈list集合
 (4)代码
     <!-- 获取值栈的list的值 -->
     <s:property value="list[0].username"/>
     <!-- 第一种写法 -->
     <s:iterator value="list">
  <s:property value="username"/>
     </s:iterator>
     <!-- 第二种写法 -->
     <hr/>
     <!-- 添加属性var表示: 在context创建值user -->
     <s:iterator value="list" var="user">
  <s:property value="#user.username"/> -- <s:property value="#user.password"/>
  <br/>
     </s:iterator>
  (5)获取值栈list集合中某一个值
     <!-- 获取值栈list里面的username的值 -->
     <!-- puser在context里面创建值,这个值是每次遍历username的内容-->
     <s:iterator value="list.{username}" var="puser">
  <s:property value="#puser"/>
     </s:iterator>

  (6)ognl条件判断
      <!-- 获取值栈的list的值,进行条件判断
  获取list里面person对象中age大于20的信息
      -->
     <s:iterator value="list.{?#this.age>20}" var="person">
  <s:property value="#person.pname"/> -- <s:property value="#person.age"/>
  <br/>
     </s:iterator>
#构建集合:
    <!-- 使用ognl构建 list集合 -->
    <s:iterator value="{'aa','bb','cc'}" var="list">
     <s:property value="#list"/>
    </s:iterator>
 <!-- 使用ognl构建 map集合 -->
    <s:iterator value="#{'ww':'WW','aa':'AA','pp':'PP'}" var="map">
     <s:property value="#map.key"/> --- <s:property value="#map.value"/>
    </s:iterator>

%号的使用:
类似于HTML中的表单的<input type="text"/>;
把当前内容作为ognl表达式使用:<s:textfield value="%{#request.msgname}"></s:textfield>;
如果就想把内容作为字符串使用:不写%{}或者加单引号<s:textfield value="%{'#request.msgname'}"></s:textfield>

$号的使用:
1)、用在国际化资源文件中,引用ognl表达式
在properties文件中,name=${\request.msgname}。
在页面中<!-- 获取国际化里面的内容 -->
    <s:text name="namekey"></s:text>
2)、在Struts2配置文件中,引用ognl表达式,需要在action中设置set方法 

猜你喜欢

转载自jackpot1234.iteye.com/blog/2315592