OGNL
本質
其實我們在平時編寫EL表達式或者利用屬性標籤的時候,都已經接觸過OGNL語法了,只是那時候不知道原來它叫這個。
OGNL表達式最大的優點就是簡單、直觀,還能自動向下轉型,OGNL一般用來簡化代碼的。例如簡化Java代碼:
user.getCustomer().getName();
((Zi)user.getCustomer()).getTrustId();-> //父類向下轉型變成子類
user是User類的對象。上面的java語句在OGNL中可以轉變成:
user.customer.name
user.customer.trustId
由此可見,OGNL語法最突出的特點是:簡化對象調用方法的代碼(簡化調用某方法取得對象的方式)
具體內容
OGNL上下文(context)實際上就是一個Map對象,可以包含一個或多個對象,其中根(root)對象是唯一的一個對象。
未指定使用上下文中的哪一個對象,則將根對象視爲表達式所依據的對象。 非根對象,要使用‘#’符號引出,例如上例的user如果非根,則要#user.customer.name這麼寫,即#getUser().getCustomer().getName()。
OGNL只有一個根對象,而Struts2根對象不是一個對象,而是一組對象——稱爲值棧(ValueStack)。
同樣的,由於ognl的語法特性,值棧中的任何對象都可以直接訪問(都屬於root根對象),而不需要使用“#” 。
Action指向的java類對象在值棧中,還在值棧的頂部,而且值棧又是OGNL的根對象,所以引用Action對應的java類對象中的屬性可以省略“#”標記。然而其餘的apllication、session等需要使用“#”才能訪問到對象。
代碼示例
話不多說,直接上代碼demo,舉例ognl語法的常規寫法和常用數據類型的相關操作。
struts.xml:設置了一個action,能跳轉到Test2Action.java類中。
<?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="default" extends="struts-default">
<action name="Test" class="com.test.Test2Action">
<result>/Test2.jsp</result>
</action>
</package>
</struts>
Test2Action.java:
public class Test2Action {
public String datePattern = "mm/dd/yyyy";
private String greeting = "Hello";
public static String EXAMPLE="static";
public static Date now(){
return new Date();
}
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
public String execute() {
ActionContext aContext = ActionContext.getContext();
Map application = aContext.getApplication();
application.put("code", "101");
return "success";
}
public String getTime() {
return new Date().toString();
}
public List<String> getCountries() {
List<String> countries = new ArrayList<String>();
countries.add("Australia");
countries.add("Fiji");
countries.add("New Zealand");
countries.add("Vanuatu");
//判斷是否爲空
countries.isEmpty();
return countries;
}
public String[] getColors() {
String[] colors = {"blue", "green", "red"};
return colors;
}
public Map<String, String> getCities() {
Map<String, String> cities = new HashMap<String, String>();
cities.put("BJ", "BeiJing");
cities.put("HRB", "Harbin");
cities.put("SH", "ShangHai");
return cities;
}
}
Test2.jsp:
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<meta charset="utf-8">
<title>OGNL實現java傳值給jsp</title>
</head>
<body>
<h2>ognl常規使用</h2><br/>
<h3>ognl在EL表達式中的使用:</h3><br/>
取得對象:${greeting}<br/>
取得application的值:${application.code}
<h3>ognl在struts2標籤的使用:</h3><br/>
問候語:<s:property value="greeting"/><br/>
日期格式:<s:property value="datePattern"/><br/>
當前日期:<s:property value="time"/><br/>
<h2>ognl結合常用數據類型的使用</h2><br/>
<h3>列表:</h3><br/>
列表的對象調用:<s:property value ='countries'/><br/>
列表第一個元素:<s:property value ='countries[0]'/><br>
列表長度:<s:property value ='countries.size()'/><br>
列表長度:<s:property value ='countries.size'/><br>
列表是否爲空:<s:property value ='countries.isEmpty()'/><br>
<h3>數組:</h3><br/>
數組的對象調用<s:property value ='colors'/><br/>
第二個元素的輸出<s:property value ='colors[1]'/><br>
數組的長度<s:property value ='colors.length'/><br>
<h3>map:</h3><br/>
map對象調用: <s:property value="cities"/><br/>
取得map中的元素"BJ": ${cities["BJ"] }<br/>
取得map中的元素"BJ":<s:property value="cities.BJ"/><br/>
取得map中的元素"BJ": <s:property value="cities['BJ']"/><br/>
Map 大小: <s:property value="cities.size"/><br/>
方法調用(是否爲空): <s:property value="cities.isEmpty"/>
</body>
</html>
【運行的訪問地址欄】:http://localhost:8080/項目名/Test(注意不是訪問Test2.jsp)
【結果】
N語法
本質
指定索引N,從N位置開始向下查找對象的屬性。例如:使用[N].xxx(N是從0開始的整數) 。因此得名[N]語法。
例如:我們在struts.xml中配置了三個action,對應的類爲Object1,2,3類。值棧中如圖所示:
這時候我們利用OGNL語法,想要取得屬性"name",那struts選哪個類的?N語法可以解決這個問題。
直接“name”取值,則默認爲“[0].name”,即選的是Object0類中的name屬性。
然而需要注意:N的含義:不是表示“獲取棧中索引爲N的xxx對象”,N是截取從位置N開始的部分棧。
例如:指定[1].name,則是從Object1類中開始找,發現這個類沒有name對象,則在棧中繼續向下尋找,找到下一個類Object2有name對象。即[1].name最終取到的值是Object2裏面的name屬性。
那如果要獲取棧中索引爲1的xxx對象怎麼辦?答:[1].top.xxx
S標籤
s標籤應用在jsp代碼中。不過要記得在jsp首行添加一下代碼表示調用:
<%@ taglib prefix="s" uri="/struts-tags" %>
1、它可以代替常規的ui控件,例如文本輸入框、表單等..
例如原html代碼:
<form action="login" method="post">
username:<input name="user.username"><br>
password:<input name="user.password"><br>
<input type="submit" value="登錄">
</form>
可以直接替換成s標籤:
<s:form action="login">
<s:textfield name="user.username" label="用戶名"></s:textfield><br/>
<s:password name="user.password" label="密碼"></s:password><br/>
<s:submit value="登錄" />
</s:form>
2、直接在頁面中實現基本操作,例如if-else判斷,for循環等....
例如,如果session中存放的用戶名是admin,則提供“添加用戶”功能:
<s:if test="#session.user.username=='admin'">
<s:a href="add.jsp">添加用戶</s:a>
</s:if>
參考資料:#、%和$符號詳解
教程網站:無意中找到的易百教程