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方法