Struts2(2):OGNL語法和N語法

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這麼寫。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章