OGNL(Object-Graph Navigation Language)是一种功能强大的表达式语言(Expression Language,简称为EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
Struts2默认的表达式语言是OGNL,OGNL是通常要结合Struts2的标签一起使用,如<s:property value="xx" />就是结合了Struts标签和OGNL表达式。
在OGNL中,经常使用到#、%等符号,下面介绍一下这几个符号的使用方法。
***OGNL中#的使用
-访问Context~
#parameters.id[0]作用相当于request.getParameter("id")
#request.userName相当于request.getAttribute("userName")
#session.userName相当于session.getAttribute("userName")
#application.userName相当于application.getAttribute("userName")
#attr.userName相当于按request,session,application的顺序读取userName属性,直到找到为止
-用于过滤和投影(projecting)集合~
Action中存在一个名为books的Collection对象及其get方法
<s:iterator value="books.{?#this.price > 35}">
<li><s:property value="title" /> - $<s:property value="price" /></li>
</s:iterator>
以上代码可以只输出book.price>35的信息,而不符合条件的对象将被过滤掉
-构造Map~
<s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}" />
<p>The value of key "foo1" is <s:property value="#foobar['foo1']" /></p>
***OGNL中%的使用
%用于表示某字符串为一个OGNL表达式。某些标签中既能接受字符串,又能接受OGNL表达式。这时候,标有%的被当做OGNL表达式并被执行,没有标有%的被当做普通的字符串。
<!-- label标签既能接受字符串,又能接受OGNL表达式,这时需要用"%"显式声明OGNL表达式 -->
<struts:form>
<struts:label label="#request.account"></struts:label> <!-- 输出字符串#request.account -->
<struts:label label="%{#request.account}"></struts:label> <!-- 输出request的account属性值 -->
</struts:form>
***简单文本 (property)
<s:property value="name">
将把Action中getName()的返回值以文本形式放到页面上
***输入框 (textfield)
<s:textfield label="%{getText('page1.name')}" name="user.name"/>
-label="%{getText('page1.name')}"~
在从Action定向到页面时,会以page1.name为key去对应locale的资源文件中取出值作为input的标签,
-name="user.name"~
在从Action定向到页面时,可以使Action.user.name的值作为input的value值,前提是要有user,name的get方法~
在页面提交至Action时,可以将input中的输入值作为参数来填充到Action.user.name中,前提是要有user,name的set方法。
***迭代器(iterator)
使用iterator标签可以对一个集合类型的对象进行迭代,例如在Action中定义一个List对象users及其get方法,存放了若干个User对象,User类有id属性及其get方法,Action转至jsp时可以使用
<s:iterator value="users">
<s:property value="id"/>
</s:iterator>
就可以将users中的每个user的id进行输出~
<s:iterator value="users">
<s:property/>
</s:iterator>
直接将每个user对象进行输出。
使用org.apache.struts2.util.Counter可以在不依赖Action中的集合对象情况下,实现简单的数字循环。
<s:bean name="org.apache.struts2.util.Counter" id="counter">
<s:param name="first" value="10" />
<s:param name="last" value="20" />
<s:param name="interval" value="2"/>
<s:iterator>
<s:property value="current"/>
<s:property/>
</s:iterator>
</s:bean>
上面的例子中,first,last,interval的值可以是动态从Action获取的,从输出结果我们可以看出,<s:property/>输出每次迭代产生的值,而
<s:property value="current"/>=<s:property/>+interval
一个简单的分页程序
<s:bean name="org.apache.struts2.util.Counter" id="counter">
<s:param name="first" value="1" />
<s:param name="last" value="totalPNum" />
<s:iterator>
<s:if test="pno==current-1"><font color="red"><s:property/></font></s:if>
<s:else>
<s:url id="url" action="userlist">
<s:param name="pno" value="current-1" />
</s:url>
<s:a href="%{url}">[<s:property/>]</s:a>
</s:else>
</s:iterator>
</s:bean>
其中,Action提供总页数(totalPNum)和当前页(pno),迭代器在1-totalPNum之间迭代,如果迭代的数字等于pno,则输出简单的文本,否则,输出带页码参数的超链接。