OGNL是一種表達(dá)式語(yǔ)言御毅,可以存取對(duì)象的屬性或者調(diào)用對(duì)象的方法,能夠遍歷整個(gè)對(duì)象的結(jié)構(gòu)圖赞别,實(shí)現(xiàn)對(duì)象屬性類型的轉(zhuǎn)換等功能滤馍。(工程Struts2_1900_OGNL
)岛琼。
這里需要做的試驗(yàn)較多,我們一個(gè)一個(gè)講解巢株。
1.訪問(wèn)值棧中的action的普通屬性
ognl.jsp
<li>1.訪問(wèn)值棧中的action的普通屬性: username = <s:property value="username"/> </li>
OgnlAction.java
//試驗(yàn)1-------
private String username;
private String password;
//試驗(yàn)1-------
public String execute(){
return SUCCESS;
}
說(shuō)明:這里的action中我們只有兩個(gè)屬性槐瑞,我們通過(guò)OGNL表達(dá)式value="username"
可以直接從值棧中取得屬性的值。我們可以在值棧中找到對(duì)應(yīng)屬性的值阁苞。
2.訪問(wèn)值棧中對(duì)象的普通屬性
ognl.jsp
<li>2.訪問(wèn)值棧中對(duì)象的普通屬性(get set方法):<s:property value="user.age"/> | <s:property value="user['age']"/> | <s:property value="user[\"age\"]"/> | wrong: <%--<s:property value="user[age]"/>--%></li>
OgnlAction.java
//試驗(yàn)2-------
private User user ;
//試驗(yàn)2-------
User.java
package com.bjsxt.struts2.ognl;
public class User {
private int age = 8;
public User(){}
public User(int age) {
super();
this.age = age;
}
@Override
public String toString() {
return "user" + age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
說(shuō)明:
- 當(dāng)我們使用地址
http://localhost:8080/Struts2_1900_OGNL/ognl.action?username=u&password=p
訪問(wèn)時(shí)我們?cè)谥禇V邪l(fā)現(xiàn)user對(duì)象是null困檩,之前我們知道struts2會(huì)幫我們實(shí)例化對(duì)象,但是這必須有個(gè)條件猬错,就是地址后面必須跟上相應(yīng)的值窗看,如:
http://localhost:8080/Struts2_1900_OGNL/ognl.action?username=u&password=p&user.age=10
這時(shí)struts2才會(huì)幫我們實(shí)例化對(duì)象,同時(shí)我們的對(duì)象中必須有無(wú)參構(gòu)造函數(shù)倦炒,因?yàn)閟truts2在實(shí)例化時(shí)需要用到显沈。當(dāng)然我們也可以自己在action方法中直接將user對(duì)象new出來(lái),這相當(dāng)于自己實(shí)例化對(duì)象了逢唤。 - 這里我們給出了幾種取得普通屬性的OGNL表達(dá)式拉讯,注意其區(qū)別。
ognl.jsp
<li>3.訪問(wèn)值棧中對(duì)象的普通屬性(get set方法): <s:property value="cat.friend.name"/></li>
OgnlAction.java
//試驗(yàn)3-------
private Cat cat ;
//試驗(yàn)3-------
Cat.java
package com.bjsxt.struts2.ognl;
public class Cat {
private Dog friend;
public Dog getFriend() {
return friend;
}
public void setFriend(Dog friend) {
this.friend = friend;
}
public String miaomiao(){
return "miaomiao";
}
}
Dog.java
package com.bjsxt.struts2.ognl;
public class Dog {
private String name ;
public Dog(){
}
public Dog(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString(){
return "dog:" + name;
}
}
說(shuō)明:此時(shí)這里就構(gòu)成了一個(gè)對(duì)象圖鳖藕,我們可以使用地址http://localhost:8080/Struts2_1900_OGNL/ognl.action?cat.friend.name=oudy
進(jìn)行訪問(wèn)魔慷,我們通過(guò)<s:property value="cat.friend.name"/>
就可以取得相應(yīng)的值。
3.訪問(wèn)值棧中對(duì)象的普通方法
ognl.jsp
<li>4.訪問(wèn)值棧中對(duì)象的普通方法:<s:property value="password.length()"/></li>
<li>5.訪問(wèn)值棧中對(duì)象的普通方法:<s:property value="cat.miaomiao()" /></li>
說(shuō)明:訪問(wèn)普通屬性中的方法我們可以直接調(diào)用著恩,而訪問(wèn)對(duì)象中的方法也類似院尔,這個(gè)比較簡(jiǎn)單蜻展。
4.方法值棧中action的普通方法
在OgnlAction.javaa
中有個(gè)名為m的方法,我們調(diào)用可以這樣:
ognl.jsp
<li>6.訪問(wèn)值棧中action的普通方法:<s:property value="m()" /></li>
5.訪問(wèn)靜態(tài)屬性和方法
ognl.jsp
<li>7.訪問(wèn)靜態(tài)方法:<s:property value="@com.bjsxt.struts2.ognl.S@s()"/></li>
<li>8.訪問(wèn)靜態(tài)屬性:<s:property value="@com.bjsxt.struts2.ognl.S@STR"/></li>
<li>9.訪問(wèn)Math類的靜態(tài)方法:<s:property value="@@max(2,3)" /></li>
S.java
package com.bjsxt.struts2.ognl;
public class S {
public static String STR = "STATIC STRING";
public static String s(){
return "static method";
}
}
說(shuō)明:我們?cè)谠L問(wèn)靜態(tài)方法時(shí)一定要在struts.xml
中設(shè)置<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
邀摆。訪問(wèn)格式是:@完整類名@靜態(tài)方法/屬性
而只有在訪問(wèn)Math類的時(shí)候使用兩個(gè)@纵顾。
6.訪問(wèn)普通類的構(gòu)造方法
ognl.jsp
<li>10.訪問(wèn)普通類的構(gòu)造方法:<s:property value="new com.bjsxt.struts2.ognl.User(8)"/></li>
說(shuō)明:類中我們覆寫(xiě)了toString方法,但是我在做試驗(yàn)的時(shí)候卻失敗栋盹,不知道為什么施逾,語(yǔ)法應(yīng)該沒(méi)有錯(cuò)誤,如果有誰(shuí)看到例获,希望能幫我解決一下汉额,不知道是不是struts2的設(shè)置變了。
7.訪問(wèn)集合(或數(shù)組)
ognl.jsp
<li>11.訪問(wèn)List:<s:property value="users"/></li>
<li>12.訪問(wèn)List中某個(gè)元素:<s:property value="users[1]"/></li>
<li>13.訪問(wèn)List中元素某個(gè)屬性的集合:<s:property value="users.{age}"/></li>
<li>14.訪問(wèn)List中元素某個(gè)屬性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li>
<li>15.訪問(wèn)Set:<s:property value="dogs"/></li>
<li>16.訪問(wèn)Set中某個(gè)元素:<s:property value="dogs[1]"/></li>
<li>17.訪問(wèn)Map:<s:property value="dogMap"/></li>
<li>18.訪問(wèn)Map中某個(gè)元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap['dog101']"/> | <s:property value="dogMap[\"dog101\"]"/></li>
<li>19.訪問(wèn)Map中所有的key:<s:property value="dogMap.keys"/></li>
<li>20.訪問(wèn)Map中所有的value:<s:property value="dogMap.values"/></li>
<li>21.訪問(wèn)容器的大姓ヌ馈:<s:property value="dogMap.size()"/> | <s:property value="users.size"/> </li>
OgnlAction.java
//試驗(yàn)4-------
private List<User> users = new ArrayList<User>();
//試驗(yàn)4-------
//試驗(yàn)5-------
private Set<Dog> dogs = new HashSet<Dog>();
//試驗(yàn)5-------
//試驗(yàn)6-------
private Map<String, Dog> dogMap = new HashMap<String, Dog>();
//試驗(yàn)6-------
public OgnlAction(){
//試驗(yàn)4-------
users.add(new User(1));
users.add(new User(2));
users.add(new User(3));
//試驗(yàn)5-------
dogs.add(new Dog("dog1"));
dogs.add(new Dog("dog2"));
dogs.add(new Dog("dog3"));
//試驗(yàn)6-------
dogMap.put("dog100", new Dog("dog100"));
dogMap.put("dog101", new Dog("dog101"));
dogMap.put("dog102", new Dog("dog102"));
}
最后我們給出試驗(yàn)結(jié)果:
11.訪問(wèn)List:[user :1, user :2, user :3]
12.訪問(wèn)List中某個(gè)元素:user :2
13.訪問(wèn)List中元素某個(gè)屬性的集合:[1, 2, 3]
14.訪問(wèn)List中元素某個(gè)屬性的集合中的特定值:1 | 1
15.訪問(wèn)Set:[dog:dog3, dog:dog1, dog:dog2]
16.訪問(wèn)Set中某個(gè)元素:
17.訪問(wèn)Map:{dog100=dog:dog100, dog101=dog:dog101, dog102=dog:dog102}
18.訪問(wèn)Map中某個(gè)元素:dog:dog101 | dog:dog101 | dog:dog101
19.訪問(wèn)Map中所有的key:[dog100, dog101, dog102]
20.訪問(wèn)Map中所有的value:[dog:dog100, dog:dog101, dog:dog102]
21.訪問(wèn)容器的大腥渌选:3 | 3
說(shuō)明:
- 1.注意在ongl中花括號(hào)可以代表一個(gè)集合,于是
users.{age}
表示的是age的一個(gè)集合收壕。 - 2.訪問(wèn)集合和訪問(wèn)數(shù)組的方式類似讥脐,這里不做試驗(yàn)。
- 3.Set集合中是沒(méi)有順序的啼器,所以第16個(gè)中取不到值。
- 4.在ognl中單引號(hào)可以表示一個(gè)字符串俱萍。
8.投影(過(guò)濾)
ognl.jsp
<li>22.投影(過(guò)濾):<s:property value="users.{?#this.age==1}[0]"/></li>
<li>23.投影:<s:property value="users.{^#this.age>1}.{age}"/></li>
<li>24.投影:<s:property value="users.{$#this.age>1}.{age}"/></li>
<li>25.投影:<s:property value="users.{$#this.age>1}.{age} == null"/></li>
說(shuō)明:
- 1.這里this表示當(dāng)前對(duì)象端壳,因?yàn)閡sers是一個(gè)集合,于是會(huì)進(jìn)行一個(gè)循環(huán)枪蘑,循環(huán)到哪個(gè)對(duì)象损谦,this就表示哪個(gè)對(duì)象。
- 2.投影中只有上面三種方式:
?#岳颇、^#照捡、$#
。第22表示判斷哪個(gè)user對(duì)象的age為1话侧,如果不加后面的[0]栗精,則打印出對(duì)象,同時(shí)對(duì)象加了中括號(hào)瞻鹏,如[user1]悲立,這就表示是一個(gè)集合,因?yàn)榭赡苡卸鄠€(gè)對(duì)象的age復(fù)合條件新博。 - 3.^#表示第一個(gè)age符合條件的對(duì)象薪夕。$#表示最后一個(gè)age符合條件的對(duì)象。
9.用 [] 訪問(wèn)元素
ognl.jsp
<li>26.[]:<s:property value="[0].username"/></li>
說(shuō)明:
- 1.當(dāng)我們使用
value="[0]"
訪問(wèn)時(shí)會(huì)打印出值棧中從上到下的所有對(duì)象赫悄。如
26.[]:[com.bjsxt.struts2.ognl.OgnlAction@1360826f, com.opensymphony.xwork2.DefaultTextProvider@5c053d81]
- 2.當(dāng)我們使用
value="[0].username"
訪問(wèn)時(shí)則會(huì)在action中找username這個(gè)屬性原献,當(dāng)在第一個(gè)action中找不到我們想要的屬性時(shí)會(huì)到第二個(gè)action中去找馏慨,而一般我們什么時(shí)候值棧中才會(huì)有多個(gè)action呢?
ognl.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="ognl" extends="struts-default">
<action name="ognl" class="com.bjsxt.struts2.ognl.OgnlAction">
<result>/ognl.jsp</result>
</action>
<action name="test" class="com.bjsxt.struts2.ognl.TestAction">
<result type="chain">ognl</result>
</action>
</package>
</struts>
可以看到當(dāng)result的類型type="chain"
時(shí)會(huì)出現(xiàn)多個(gè)action姑隅。此時(shí)我們使用地址:http://localhost:8080/Struts2_1900_OGNL/tesst.action
進(jìn)行訪問(wèn)写隶,這時(shí)我們就可以在值棧中看到兩個(gè)action。
最后我們給出struts.xml
:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<include file="/com/bjsxt/struts2/ognl/ognl.xml"></include>
</struts>