三大框架(ssh)學習——struts深入學習(OGNL)
OGNL全稱是Object-Graph Navigation Language(物件圖形導航語言),相對於EL語言,除了保持EL語言的優點外,他的其他優點如下:
- 能夠訪問物件的普通方法
- 能夠訪問類的靜態屬性和靜態方法
- 強大的操作集合類物件的能力
- 支援賦值操作和表示式串聯
- 訪問OGNL上下文和ActionContext
為了測試OGNL,我們寫一個基本的TestOGNLAction,以及一個顯示結果的頁面ok.jsp。同時為了配合操作,我們寫兩個javabean:User和Address,他們的內容和配置如下:
package com.bjsxt.struts.test; public class Address { private String country; private String city; private String street; //限於篇幅,get和set方法省略! public Address(String country, String city, String street) { super(); this.country = country; this.city = city; this.street = street; } public } } |
package com.bjsxt.struts.test; public class User { private int id; private String uname; private String pwd; private Address addr; public User(int id, String uname, String pwd) { super(); this.id = id; this.uname = uname; this.pwd = pwd; } public User(String uname, String pwd) { super(); this.uname = uname; this.pwd = pwd; } public User() { } //限於篇幅,get和set方法省略! } |
package com.bjsxt.struts.test; import com.opensymphony.xwork2.ActionSupport; public class TestOGNLAction extends ActionSupport{ private String uname; private User user; public String execute() throws Exception { //在此處增加測試程式碼 return this.SUCCESS; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } } |
<?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEstrutsPUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constantname="struts.i18n.encoding"value="gbk"/> <constantname="struts.devMode"value="true"/> <packagename="test"namespace="/"extends="struts-default"> <actionname="testOgnl"class="com.bjsxt.struts.test.TestOGNLAction"> <resultname="success">/ok.jsp</result> </action> </package> </struts> |
<%@pagelanguage="java"import="java.util.*"pageEncoding="gbk"%> <%@taglibprefix="s"uri="/struts-tags"%> <!DOCTYPEHTMLPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>測試OGNL</title> </head> <body> </body> </html> |
OGNL獲得上下文中的屬性和物件導航
- 操作OgnlValueStack中屬性
private String uname; private User user; public String execute() throws Exception { //增加測試程式碼 uname="老高"; user = new User("root","123456"); user.setAddr(new Address("中國","北京","海淀區")); return this.SUCCESS; } |
<body> <p><s:propertyvalue="uname"/></p> <p><s:propertyvalue="user.addr.country"/></p> <s:debug></s:debug> <!-- 我們可以通過debug標籤檢視ActionContext中的情況 --> </body> |
結果如下: |
- 操作AcitionContext其他域中的屬性
public String execute() throws Exception { //增加測試程式碼 User u = new User("root","123456"); u.setAddr(new Address("中國","北京","海淀區")); ActionContext context = ActionContext.getContext(); context.put("a", "ActionContext中的值"); ((Map)context.get("request")).put("b","request中的值"); ((Map)context.get("session")).put("c","session中的值"); ((Map)context.get("application")).put("d","session中的值"); return this.SUCCESS; } |
<body> <% request.setAttribute("r","rrr"); pageContext.setAttribute("p","ppp"); %> <p><s:propertyvalue="#a"/></p> <p><s:propertyvalue="#request.b"/></p> <p><s:propertyvalue="#parameters.param1[0]" /></p> <p><s:propertyvalue="#session.c"/></p> <p><s:propertyvalue="#application.d"/></p> <p><s:propertyvalue="#attr.p"/></p> <s:debug></s:debug> <!-- 我們可以通過debug標籤檢視ActionContext中的情況 --> </body> |
結果如下: |
OGNL中運算子
- .和[]操作符
<body> <% request.setAttribute("r","rrr"); %> <p><s:propertyvalue="#request.r"/></p> <p><s:propertyvalue='#request["r"]'/></p> <p><s:propertyvalue='#request[#parameters.param2[0]]'/></p> <s:debug></s:debug> <!-- 我們可以通過debug標籤檢視ActionContext中的情況 --> </body> |
測試: |
通過上面測試,我們總結:
-
-
- 點運算子操作方便,較常用。
- []運算子操作不方便,但是功能強大,可以傳入變數值,動態取值!
-
- 普通運算子
OGNL支援所有的JAVA運算子。
<body> <% request.setAttribute("r","rrr"); %> <p><s:propertyvalue="3*3"/></p> <p><s:propertyvalue="3==3"/></p> <p><s:propertyvalue="#request.r==null"/></p> <p><s:propertyvalue="3+3"/></p> <p><s:propertyvalue="3+'3'"/>--${3+'3'}</p> <!-- 字串連線符,這點不同於EL表示式--> <p><s:propertyvalue="3>2&&1>2"/></p> <p><s:propertyvalue="3>2?'aa':'bb'"/></p> <hr/> <s:debug></s:debug> <!-- 我們可以通過debug標籤檢視ActionContext中的情況 --> </body> |
結果: |
- 賦值操作
<body> <% request.setAttribute("r","rrr"); request.setAttribute("r2","r2r2"); %> <p><s:propertyvalue="#request.r='ppp'"/></p> <p><s:propertyvalue="#request.r=#request.r2"/></p> <hr/> <s:debug></s:debug> </body> |
結果: |
OGNL操作集合
- List/ SetList的語法:{e1,e2,e3}。
<body> <s:setvar="list"value="{'a','b','c'}"scope="request"></s:set> <p><s:propertyvalue="#request.list.get(2)" /></p> </body> |
結果: |
- Map
<body> <% request.setAttribute("a","123456"); %> <s:setvar="m"value="#{'name':'老高','pwd':#request.a}" scope="request"></s:set> <p><s:propertyvalue="#request.m.name"/></p> <p><s:propertyvalue="#request.m.pwd"/></p> </body> |
結果: |
- 集合中查詢元素:in和not in操作符
<body> <s:setvar="s"value="{'a','b','c'}"scope="request"></s:set> <s:setvar="m"value="#{'name':'老高','pwd':'123456'}" scope="request"></s:set> <p><s:propertyvalue="'a' in {'a','b','c'}"/></p> <p><s:propertyvalue="'a' not in #request.s" /></p> <p><s:propertyvalue="'name' in #request.m.keys"/></p> <p><s:propertyvalue="'老高' in #request.m.values" /></p> </body> |
- 過濾/投影
我們把過濾集合中的元素產生一個子集合,叫做投影
?---符合選擇邏輯的所有元素
^---符合選擇邏輯的第一個元素
$---符合選擇邏輯的最後一個元素
#this---表示集合中的元素
<%@pagelanguage="java"import="java.util.*,com.bjsxt.struts.test.*"pageEncoding="gbk"%> <%@taglibprefix="s"uri="/struts-tags"%> <!DOCTYPEHTMLPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>測試OGNL</title> </head> <body> <% User u1 = new User("張三","123456"); User u3 = new User("王五","123456"); User u5 = new User("高淇","654321"); User u6 = new User("馬士兵","654321"); List list = new ArrayList(); list.add(u1); list.add(u3); list.add(u5); list.add(u6); request.setAttribute("s",list); %> <s:setvar="s1"value="#request.s.{?#this.pwd=='654321'}"scope="request"></s:set> <s:iteratorvalue="#request.s1"var="temp"> <p><s:propertyvalue="#temp.uname"/></p> </s:iterator> </body> </html> |
執行結果: |