ValueStack基礎:OGNL
要了解ValueStack,必須先理解OGNL(Object Graphic Navigatino Language)!
OGNL是Struts2中使用的一種表達式語言,它可以用于JSP的標簽庫中,以便能夠方便的訪問各種對象的屬性;它用于界面將參數傳遞到Action(并進行類型轉換)中;它還可以用于struts2的配置文件中!所以,非常有必要理解OGNL的基本機制。
?
Root對象
OGNL稱為對象圖導航語言。所謂對象圖,即以任意一個對象為根,通過OGNL可以訪問與這個對象關聯的其它對象。如:
package?cn.com.leadfar.struts2.actions; ? public?class?User { ????private?String?username; ????private?Group?group; ??? ????public?String getUsername() { ???????return?username; ????} ????public?void?setUsername(String username) { ???????this.username?= username; ????} ??? ????public?Group getGroup() { ???????return?group; ????} ????public?void?setGroup(Group group) { ???????this.group?= group; ????} } ? |
package?cn.com.leadfar.struts2.actions; ? public?class?Group { ????private?String?name; ????private?Organization?org; ????public?String getName() { ???????return?name; ????} ? ????public?void?setName(String name) { ???????this.name?= name; ????} ? ????public?Organization getOrg() { ???????return?org; ????} ? ????public?void?setOrg(Organization org) { ???????this.org?= org; ????} } ? |
package?cn.com.leadfar.struts2.actions; ? public?class?Organization { ????private?String?orgId; ? ????public?String getOrgId() { ???????return?orgId; ????} ? ????public?void?setOrgId(String orgId) { ???????this.orgId?= orgId; ????} } ? |
?
上面三個類,描述了通過一個User對象,可以導航到Group對象,進而導航到Organization對象,以User對象為根,一個對象圖如下所示:
?
User(root)
???-- username
???-- group
??????-- name
??????-- org
?????????-- orgId
?
在真實的環境下,這個對象圖可能會極其復雜,但是通過基本的getters方法,都應該能夠訪問到某個對象的其它關聯對象。【對象圖的導航,必須通過getters方法進行導航】
?
下述代碼將創建一個User對象,及其相關的一系列對象:
???????User user =?new?User(); ???????Group g =?new?Group(); ???????Organization o =?new?Organization(); ????????o.setOrgId("ORGID"); ???????g.setOrg(o); ???????user.setGroup(g); |
?
如果通過JAVA代碼來進行導航(依賴于getters方法),導航到Organization的orgId屬性,如下所示:
?
//用JAVA來導航訪問 user.getGroup().getOrg().getOrgId(); ? |
?
【注意:導航的目的,是為了獲取某個對象的值或設置某個對象的值或調用某個對象的方法!】
【注意:OGNL表達式語言的真正目的,是為了在那些不能寫JAVA代碼的地方執行JAVA代碼,或者是為了更方便地執行JAVA代碼】
?
利用OGNL進行導航的代碼如下:
?
???????//利用OGNL表達式訪問 ???????String value = (String)Ognl.getValue("group.org.orgId", user); ? |
Ognl.getValue()方法的第一個參數,就是一條OGNL表達式,第二個參數是指定在表達式中需要用到的root對象!
完整代碼如下:
????public?void?testOgnl01()?throws?Exception{ ???????User user =?new?User(); ???????user.setUsername("張三"); ?????? ???????//利用OGNL表達式訪問user對象的username屬性 ???????String value = (String)Ognl.getValue("username", user); ???????log(value); ????} ??? ????public?void?testOgnl02()?throws?Exception{ ???????User user =?new?User(); ???????Group g =?new?Group(); ???????Organization o =?new?Organization(); ???????o.setOrgId("ORGID"); ???????g.setOrg(o); ???????user.setGroup(g); ?????? ???????//用JAVA來導航訪問 ???????log(user.getGroup().getOrg().getOrgId()); ?????? ???????//利用OGNL表達式訪問 ???????String value = (String)Ognl.getValue("group.org.orgId", user); ???????log(value); ????} ??? ????public?void?testOgnl03()?throws?Exception{ ???????User user =?new?User(); ???????Group g =?new?Group(); ???????Organization o =?new?Organization(); ???????o.setOrgId("ORGID"); ???????g.setOrg(o); ???????user.setGroup(g); ?????? ???????//用JAVA來導航訪問 ???????log(user.getGroup().getOrg().getOrgId()); ?????? ???????//也可以在表達式中使用#root來代表root對象 ???????String value = (String)Ognl.getValue("#root.group.org.orgId", user); ???????log(value); ????} ????private?void?log(Object o){ ???????System.out.println(o); ????} |
?
?
Context對象
在OGNL的表達式中,有可能需要訪問到多個毫不相干的對象,這時候,我們需要給OGNL傳遞一個Map類型的對象,把表達式中需要用到的對象放到Map中即可!這個Map對象,稱為context。
?
要在表達式中訪問到context中的對象,需要使用“#對象名稱”的語法規則。
如:
????public?void?testOgnl04()?throws?Exception{ ???????User user =?new?User(); ???????user.setUsername("張三"); ???????Group g =?new?Group(); ???????Organization o =?new?Organization(); ???????o.setOrgId("ORGID"); ???????g.setOrg(o); ???????user.setGroup(g); ?????? ???????User user2 =?new?User(); ???????user2.setUsername("李四"); ?????? ???????/** ????????*?所謂context其實就是一個Map類型的對象。主要是因為在OGNL中,不支持多個root對象,那么 ????????*?如果需要在表達式中訪問更多毫不相干的對象時,只能通過一個Map來把這些對象統一傳遞給OGNL。 ????????*/ ???????Map context =?new?HashMap(); ???????context.put("u1", user); ???????context.put("u2", user2); ?????? ???????//在表達式中需通過“#+對象的名稱”來訪問context中的對象 ???????//如果表達式中沒有用到root對象,那么可以用任意一個對象代表root對象! ???????String value = (String)Ognl.getValue("#u1.username + ',' + #u2.username", context,new?Object()); ???????log(value); ????} ??? ????public?void?testOgnl05()?throws?Exception{ ???????User user =?new?User(); ???????user.setUsername("張三"); ???????Group g =?new?Group(); ???????Organization o =?new?Organization(); ???????o.setOrgId("ORGID"); ???????g.setOrg(o); ???????user.setGroup(g); ?????? ???????User user2 =?new?User(); ???????user2.setUsername("李四"); ?????? ???????User user3 =?new?User(); ???????user3.setUsername("王五"); ?????? ???????Map context =?new?HashMap(); ???????context.put("u1", user); ???????context.put("u2", user2); ?????? ???????//給OGNL傳遞root對象及context對象,以便解釋對應的表達式 ???????String value = (String)Ognl.getValue("#u1.username + ',' + #u2.username + ',' + username", context,user3); ???????log(value); ????} |
?
利用OGNL表達式進行賦值
?
OGNL表達式也可以用于賦值操作。
????public?void?testOgnl06()?throws?Exception{ ???????User user =?new?User(); ?????? ???????//調用setValue()方法來進行賦值 ???????//第一個參數:OGNL表達式 ???????//第二個參數:root對象 ???????//第三個參數:要賦的值????? ???????Ognl.setValue("username", user,?"張三"); ? ???????log(user.getUsername()); ????} ??? ????public?void?testOgnl07()?throws?Exception{ ???????User user =?new?User(); ?????? ???????Map context =?new?HashMap(); ???????context.put("u", user); ?????? ???????//調用setValue()方法來進行賦值 ???????//第一個參數:OGNL表達式 ???????//第二個參數:context對象 ????????//第三個參數:root對象 ???????//第四個參數:要賦的值 ???????Ognl.setValue("#u.username", context,?new?Object(),?"張三"); ? ???????log(user.getUsername()); ????} ??? ????public?void?testOgnl08()?throws?Exception{ ???????User user =?new?User(); ?????? ???????Map context =?new?HashMap(); ???????context.put("u", user); ??????? ???????//利用賦值符號"="來進行賦值 ???????Ognl.getValue("#u.username = '李四'", context,?new?Object()); ? ???????log(user.getUsername()); ????} ??? ????public?void?testOgnl09()?throws?Exception{ ???????User user1 =?new?User(); ???????User user2 =?new?User(); ???????Map context =?new?HashMap(); ???????context.put("u1", user1); ???????context.put("u2", user2); ?????? ???????//在一個表達式中可以用逗號分隔,同時執行多個表達式 ???????Ognl.getValue("#u1.username = '李四',#u2.username='王五'", context,?new?Object()); ? ???????log(user1.getUsername()); ???????log(user2.getUsername()); ????} |
?
利用OGNL調用對象的方法
?
????//************************* OGNL調用對象的方法?*****************************// ????public?void?testOgnl10()?throws?Exception{ ???????User user =?new?User(); ?????? ???????//如果是調用root對象的方法,可以直接使用方法的名稱來調用方法 ???????Integer value = (Integer)Ognl.getValue("addSomething(1,1)", user); ???????log(value); ????} ??? ????public?void?testOgnl11()?throws?Exception{ ???????User user =?new?User(); ???????user.setUsername("李四"); ???????//如果是調用root對象的方法,可以直接使用方法的名稱來調用方法 ???????String value = (String)Ognl.getValue("getUsername()", user); ???????log(value); ????} ??? ????public?void?testOgnl12()?throws?Exception{ ???????User user =?new?User(); ???????Ognl.getValue("setUsername('王五')", user); ???????String value = (String)Ognl.getValue("getUsername()", user); ???????log(value); ????} ??? ????//************************* OGNL調用靜態方法和變量?*********************// ????public?void?testOgnl13()?throws?Exception{ ???????User user =?new?User(); ???????user.setUsername("王五"); ???????//調用靜態變量 ???????//注意:out是System中的靜態變量,out是PrintStream類型的一個對象 ???????//而println()則是out這個對象中的實例方法(不是靜態方法) ???????//調用靜態方法,需要在類名和變量名前面加上@來調用,對于實例方法,用"."來調用 ???????Ognl.getValue("@System@out.println(username)", user); ????} ??? ????public?void?testOgnl14()?throws?Exception{ ???????User user =?new?User(); ???????user.setUsername("wangwu"); ???????//調用靜態方法,注意使用全路徑類名 ???????Ognl.getValue("@System@out.println(@cn.com.leadfar.utils.Utils@toUpperCase(username))", user); ????} |
?
利用OGNL訪問數組、集合對象
?
????public?void?testOgnl15()?throws?Exception{ ?????? ???????Object root =?new?Object(); ???????Map context =?new?HashMap(); ?????? ???????//利用OGNL創建java.util.List對象 ???????List list = (List)Ognl.getValue("{123,'xxx','kdjfk'}", context, root); ???????context.put("list", list); ?????? ???????//利用OGNL創建數組 ???????int[] intarray = (int[])Ognl.getValue("new int[]{23,45,67}", context, root); ???????context.put("intarray", intarray); ?????? ???????//利用OGNL表達式創建java.util.Map對象 ???????Map mapvalue = (Map)Ognl.getValue("#{'listvalue':#list,'intvalue':#intarray}", context, root); ???????context.put("mapvalue", mapvalue); ?????? ???????//利用OGNL表達式訪問這些數組和集合對象 ???????Ognl.getValue("@System@out.println(#list[1])", context,root); ???????Ognl.getValue("@System@out.println(#intarray[2])", context,root); ???????Ognl.getValue("@System@out.println(#mapvalue.listvalue[0])", context,root); ???????Ognl.getValue("@System@out.println(#mapvalue['intvalue'][0])", context,root); ????} ??? ????public?void?testOgnl16()?throws?Exception{ ?????? ???????List root =?new?ArrayList(); ???????User user1 =?new?User(); ???????user1.setUsername("張三"); ???????User user2 =?new?User(); ???????user2.setUsername("李四"); ???????root.add(user1); ???????root.add(user2); ?????? ???????//如果root對象是List類型 ???????log(Ognl.getValue("#root[0].username", root)); ???????log(Ognl.getValue("#root[1].username", root)); ????} |
?
本文轉自農夫山泉別墅博客園博客,原文鏈接:http://www.cnblogs.com/yaowen/p/4826365.html,如需轉載請自行聯系原作者