Struts2.2 OGNL

OGNL ,做爲Struts2 一大亮點,感受也是Struts2 中相對最難理解的一部分了。因此這裏認真的總結學習一下。javascript

值棧分析:html

MVC 請求處理流程中,牽涉的數據種類比較多,框架使用ValueStack 數據結構對這些數據結構進行有機的整合,便於統一管理。充分認識ValueStack 數據結構能夠便於框架使用者輕鬆自如獲取所需的數據。java

ValueStack 由ValueStack Contents 和Stack Context 兩部分構成web

    每一個請求都會生成一個對應的Action 實例,每個動做在執行相應方法( 默認execute 方法) 以前,都會建立一個ValueStack 的對象。ValueStack 用來保存這個動做對象和其餘對象( 請求處理所涉及的數據);sql

    ValueStack 對象至關於一個棧,它貫穿整個Action 的生命週期,每一個Action 類的對象實例都會擁有一個ValueStack 對象。數據庫

    當Struts2 接受到一個*.action 請求後,並非直接調用Action 方法,而是先將Action 類的相應屬性放到ValueStack 對象的頂層節點apache

    值棧也是位於內存中,它也是和parameters 、request 、session 、application 、attr 對象放在一塊兒的。值棧屬於ONGLContext 裏面的根對象。也就是說它位於整個內存中最最重要的地方,因此叫根對象瀏覽器

根對象和另外五個對象是有區別的,根對象能夠省寫# 號,好比<s:property value="user.username"/> 。值棧的生命週期與request 請求相關,每次請求產生一個值棧。默認全部的Action 會被自動放到值棧裏服務器

生命週期內置對象被封裝在一個Map 結構中。session

在跳轉的頁面上加一個struts 標籤-<s:debug/> 能夠看到ValueStack 結構。

 

務器跳轉時共用值棧:

 

假設從一個Action1 經過服務器跳轉到Action2 的話,就意味着這兩個Action 是共享一個值棧的,由於一次請求只使用一個值棧。這時內存中狀況是這樣的:首先接收到Action1 請求後,會產生一個值棧,在棧頂存放Action1對象以及它全部的屬性,而後通過服務器跳轉到Action2 ,這時就會把Action2 對象壓入值棧的棧頂位置,此時Action1 對象以及它的全部屬性就位於棧底了。

 

取值過程(原則:後進先出):

棧的特徵是後進先出。因此首先到棧頂的對象裏查找是否存在這個屬性,若是棧頂的Action2 對象中不存在這個屬性的話,它就會繼續向下尋找直至棧底對象,一直查找是否存在這個屬性,若是最後找到該屬性的話,那麼就會在JSP 頁面中經過<s:property value="username"/> 輸出屬性值。若是在Action2 和Action1 都有一個同名的同類型的username 屬性的話,那麼將輸出Action2 中的屬性值。由於它是先從棧頂開始尋找屬性的,值棧的特徵就是後進先出 ,但有個前提:請求過程是經過服務器跳轉的。

 

三個語法:

假設此時想要獲取Action11 中的username 屬性的話,就可使用值棧的Top 語法 或者N 語法 。 
1 、使用Top 語法 獲取值棧中的第二個對象的屬性:

<s:property value="[1].top.username"/> 
2 、使用N 語法 獲取值棧中的第二個對象的屬性:<s:property value="[1].username"/> 
3 、@ 語法 ,例如使用@ 語法調用Action 中的靜態方法:<s:property value="@vs @getVOMethod()"/> 
@vs @get() 等價於@vs1@getVOMethod() ,指的是棧頂對象的靜態getVOMethod() 方法
同理@vs2@getVOMethod() 就是取值棧中第二個對象的靜態getVOMethod() 方法

 

客戶端跳轉時使用各自的值棧:

假如中間某一個步驟中出現了客戶端跳轉的話,那麼兩個Action 所使用的就是兩個不一樣的值棧了。因此在Action2中就不能再使用Action1 中的屬性了,在最後跳轉到的JSP 頁面中也就沒法獲取Action1 的屬性了。即從Action2 跳轉到JSP 頁面時使用的是redirect 的話,那麼最後值棧中是沒有任何的Action 對象的。這個時候咱們能夠經過連接傳參,好比<result type="redirect">test.jsp?netname=${username}</result> 
意思就是取出Action2 中的username 屬性做爲參數,經過瀏覽器地址欄傳遞到JSP 頁面中
而後使用OGNL 中的# 號 獲取Paraments 對象的屬性,即<s:property value="#parameters.netname"/> 就能夠取到值了。

 

手工向值棧中壓入對象:

正 常狀況下值棧保存的是Action 對象,而咱們也能夠直接往值棧中添加其它對象,這時能夠在Action 中添加以下代碼向值棧中添加對象:

ActionContext.getContext.getValueStack().push(new Student("xdwang",23)); 
並且咱們手工往值棧中添加的Student 對象會位於棧頂 。這是由於Struts2 會首先初始化Action ,而後才能調用它的方法。初始化Action 的時候,便把Action 放到值棧中了,而後在執行它的execute() 方法時,就又往值棧中添加了Student 對象。

 

OGNL 歷史:

    OGNL 最初是爲了可以使用對象的屬性名來創建 UI 組件 (component) 和 控制器 (controllers) 之間的聯繫,簡單來講就是:視圖與控制器之間數據的聯繫 。後來爲了應付更加複雜的數據關係。

 

什麼是OGNL :

OGNL 是 Object-Graph Navigation Language 的縮寫, 對象圖形導航語言 , ,從語言角度來講:它是一種操做複雜數據結構的經常使用語言 ,它旨在提供一個更高抽象度語法來對 java 對象圖進行導航。

能夠存取對象的任意屬性,調用對象的方法,遍歷整個對象的結構圖,實現字段類型轉化等功能。它使用相同的表達式去存取對象的屬性;

    對象經過OgnlContext上下文對象來管理。

    OGNL可讓咱們用很是簡單的表達式訪問對象層。

 

OGNL 應用:

1 、做爲 GUI 元素(textfield,combobox, 等)到模型對象的綁定語言;

2 、數據庫表到 Swing 的 TableModel 的數據源語言;

3 、web 組件和後臺 Model 對象的綁定語言 (WebOGNL,Tapestry,WebWork,WebObjects) ;

4 、做爲 Jakarata Commons BeanUtils 或者 JSTL 的表達式語言的一個更具表達力的替代語言;

 

爲何須要表達式語言 (EL)

表達式語言(EL)本質上被設計爲:幫助你使用簡單的表達式來完成一些「經常使用」的工做。一般狀況下,ELs 能夠在一些框架中找到,它被是用來簡化咱們的工做。例如:你們熟知的 Hibernate,使用 HQL(Hibernate Query Language) 來完成數據庫的操做,HQL 成了開發人員與複查的 SQL 表達式之間的一個橋樑。 在 web 框架下,表達式語言起到了類似的目的。它的存在消除了重複代碼的書寫。例如:當沒有 EL 的時候,爲了從 session 中獲得購物車而且將 ID 在網頁上呈現出來,當直接在 jsp 中使用 java 代碼來完成的時候,通常是:

Jsp代碼    收藏代碼
  1. <%   
  2.     ShoppingCart cart = (ShoppingCart) session.get("cart");   
  3.     int id = cart.getId();   
  4.     %>   
  5.     <%= id%>  

 

你也能夠將這些 code 壓縮成一句,以下,可是如今代碼就很不直觀,且不可讀。另外,雖然變成了一句,可是與上面的原始的例子同樣,也包含了一樣的表達式。例如:類型轉換:轉換 成 ShoppingCart 。這裏只不過是將原來的三個表達式變成了一句,其複雜度是沒有獲得簡化的。

Jsp代碼    收藏代碼
  1. <%= ((ShoppingCart) session.get("cart")).getId() %>  

 

當在 web 框架中使用表達式語言的時候,則能夠有效的處理這種代碼的複雜性。而不須要你,調用 servelet API,類型轉換,而後再調用 getter 方法,多數的 Els 均可將這個過程簡化爲相似於:#session.cart.id 這中更可讀的表達式。 表達式:#session.cart.id 與 java 代碼不同的是:沒有 java 代碼的 get 方法調用和類型轉換。由於這些操做是很是「經常使用」的,這時候使用 EL 就瓜熟蒂落了,使用 EL 能夠「消除」這些代碼。

 

OGNL標識符:

    「$」有兩個主要的用途:

一、 用於在國際化資源文件中,引用OGNL表達式:

validation.require=${getText(fileName)} is required

二、 在Struts 2配置文件中,引用OGNL表達式:

Xml代碼    收藏代碼
  1. <action name="AddPhoto" class="addPhoto">  
  2.      <result type="redirect">  
  3.         ListPhotos.action?albumId=${albumId}  
  4.      </result>  
  5. </action>  

 

「# 」, 通常用於取出堆棧上下文中存放的對象和過濾、投影集合。這裏咱們能夠將 # 理解爲ActionContext.getContext()

1 、取出堆棧上下文:

名稱

做用

Demo

attr

用於按 request>>session>>application順序訪問其屬性

#attr.userName 至關於按順序從三個範圍讀取 userName 屬性直到找到爲止

request

包含當前 HttpServletRequest 的屬性的Map

#request.userName 至關於request.getAttribute("userName")

session

包含當前 HttpSession 的屬性的 Map

#session.userName 至關於session.getAttribute("userName")

application

包含當前應用的 ServletContext 的屬性的Map

#application.userName 至關於application.getAttribute("userName")

parameters

包含當前 HTTP 請求參數的 Map

#parameters.id[0] 至關於request.getParameter("id")

二、 用於過濾和投影(projecting)集合

如person.{?#this.age>20}

? -- 獲取集合中全部知足選擇邏輯的對象( 拿sql 來作比例就是"select * from xxx where age>20")

^ -- 獲取集合中第一個知足選擇邏輯的對象( 拿sql 來作比例就是"select top(1) from xxx where age>20")

$ -- 獲取集合中最後一個知足選擇邏輯的對象

 

    %:用途是在標識的屬性爲字符串類型時,計算OGNL表達式的值,即將本來的文本屬性解析爲ognl,對於原本就是ognl的屬性不起做用

Jsp代碼    收藏代碼
  1. <s:url value="test.jsp?age=#userlist['admin']">→test.jsp?#userlist['admin']---可見當字符串與OGNL表達式串起來時,只會被看成字符串對待,並不執行  
  2. <s:url value="test.jsp?age=%{#userlist['admin']}">→test.jsp?age=44---使用了該符號,就可使得OGNL表達式被執行  
 
Jsp代碼    收藏代碼
  1. <s:set name="hello" value="5"></s:set>  
  2. <s:property value="#hello" />   
  3. <s:property value="%{#hello}" />   
  4. <s:if test="%{#hello==5}">你好</s:if>  
  5. <s:if test="#hello==5">你好</s:if>  
  6.   
  7. <s:set name="china" value="'你好'"></s:set>  
  8. <s:property value="#china" />   
  9. <s:property value="%{#china}" />   
  10. <s:if test="%{#china=='你好'}">你好1</s:if>  
  11. <s:if test="#china=='你好'">你好2</s:if>  

 

注意上面的你好須要加引號,不然沒有值;

 

獲取Action 中的屬性值或Action 對象的某某屬性值

利用 Struts2 標籤的 <s:property> 能夠直接獲取 Action 中的引用類型 user 裏面的 name 屬性。一樣能夠經過 user.address.addr 獲取 user 中引用類型 address 中的 addr 屬性的值 
像這種一層一層往下傳遞的訪問方式 , 即所謂的導航 , 也就是一步步的往下調用

 

調用Action 的對象裏面的普通方法:

默認的會把 Action 放到值棧裏面 , 而值棧在訪問的時候 , 並不須要值棧的名字 
當咱們調用 <s:property value="user.getVOMethod()"/> 的時候。它會自動到值棧裏面查找Action對象裏面有沒有user對象,而後它就發現有user。而後它就再找user裏面有沒有getVOMethod()方法,而後它發現有,因而調用getVOMethod()。實際上調用User中的getVOMethod()方法的過程與獲取表單中的姓名密碼的方式都是相同的,都是到值棧裏面查找 ,找是否存在user對象,若是存在,接着查找user中是否存在某某屬性或方法。

 

調用Action 中的靜態方法:

    一樣咱們也能夠在 JSP 頁面中寫一個 OGNL 表達式調用 Action 中的靜態方法 , 調用 Action 中的靜態方法時, 與調用 user 對象的 getVOMethod() 方法的過程 , 是大相徑庭的。此時 value 的寫法是固定的 , 以 開頭, 後面跟上具體的包名 , 而後 加上靜態方法 ,好比 <s:property value="@com.jadyer.action.LoginAction@getStatic()"/> 。 另外 user 對象是 LoginAction 中的一個屬性 ,這個屬性會自動的放到值棧裏面, 而值棧調用的時候 , 不用加上 或者包名等等 , 因此直接user.getVOMethod() 就能夠了。

 

調用JDK 類中的靜態方法:

    可 以使用 <s:property value="@@floor(46.58)"/> 輸出 floor() 的執行結果。這就意味着 若是不在@@中指定類 的話, 默認的就表示java.lang.Math類 ,當前大多數狀況下,咱們都不會省略這個類,都會寫全了的,而後在後面加上靜態方法。

 

集合的僞屬性:

OGNL 可以引用集合的一些特殊的屬性 , 這些屬性並非 JavaBean 模式 , 例如 size() 、 length() 。當表達式引用這些屬性時,OGNL會調用相應的方法,這就是僞屬性
好比獲取List的大小: <s:property value="testList.size"/> 
List的僞屬性: size、isEmpty、iterator
Set的僞屬性: size、isEmpty、iterator
Map的僞屬性: size、isEmpty、keys、values
Iterator的僞屬性: next、hasNext
Enumeration僞屬性: next、hasNext、nextElement、hasMoreElements

 

說明:

1 、獲取集合中元素的實質就是調用它的toString() 方法;

       2 、當OGNL 取不到值的時候,它是不會報錯的,而是什麼都不顯示出來;

       3 、<s:property value="[0]"/> 返回的是ValueStack 中從上至下的全部的Object ,<s:property value="[1]"/>返回的是ValueStack 中從上至下的第二個Object ;

       4 、<s:property value="[0].username"/> 返回的是成員變量username 的值。假設ValueStack 中存在兩個Action 的話,若是第一個Action 若是沒有username 變量,那麼它會繼續找第二個Action 。那麼在什麼狀況下ValueStack 中會存在兩個Action 呢?答案是在struts.xml 中配置的是從一個Action 經過<result type="chain"> 跳轉到另外一個Action ;

5 、<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>

在Struts2.1.6 、Struts2.2 中必須設置struts.ognl.allowStaticMethodAccess 爲true 以後才容許使用OGNL 訪問靜態方法。而在Struts2.0.11 則無需設置,便可直接訪問;

經過下面的Demo發現2.2版本中若是不在Struts.xml中配置< constant name ="struts.ognl.allowStaticMethodAccess" value = "true" /> 會出現普通類中的靜態屬性和方法能夠訪問,而Action中的靜態屬性和方法以及jdk中的靜態屬性方法都沒法訪問。

 

Demo 

web.xml :

Xml代碼    收藏代碼
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
  5.     id="WebApp_ID" version="2.5">  
  6.     <display-name>OGNLDemo</display-name>  
  7.     <filter>  
  8.         <filter-name>struts2</filter-name>  
  9.         <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>  
  10.     </filter>  
  11.     <filter-mapping>  
  12.         <filter-name>struts2</filter-name>  
  13.         <url-pattern>/*</url-pattern>  
  14.     </filter-mapping>  
  15.     <welcome-file-list>  
  16.         <welcome-file>login.jsp</welcome-file>  
  17.     </welcome-file-list>  
  18. </web-app>  

 

struts.xml :

Xml代碼    收藏代碼
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE struts PUBLIC  
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"  
  4.     "http://struts.apache.org/dtds/struts-2.1.7.dtd">  
  5. <struts>  
  6.     <constant name="struts.ognl.allowStaticMethodAccess" value="true"/>  
  7.     <package name="ognl" extends="struts-default">  
  8.         <action name="login" class="com.iflytek.action.LoginAction">  
  9.             <result name="input">/login.jsp</result>  
  10.             <result name="success">/loginSuc.jsp?netname=xdwang</result>  
  11.             <!-- <result name="success" type="redirect">/loginSuc.jsp?netname=xdwang</result>   
  12.                 <result name="success" type="redirect">/loginSuc.jsp?netname=${user.username}</result> -->  
  13.         </action>  
  14.     </package>  
  15. </struts>    
 

 

Address.java:

Java代碼    收藏代碼
  1. package com.iflytek.entity;  
  2.   
  3. /** 
  4.  * @author xdwang 
  5.  *  
  6.  * @ceate 2012-6-27 上午12:29:38 
  7.  *  
  8.  * @description Address實體 
  9.  *  
  10.  */  
  11. public class Address {  
  12.     public static final String TIPS = "xdwang";  
  13.   
  14.     private String addr;  
  15.   
  16.     public String getAddr() {  
  17.         return addr;  
  18.     }  
  19.   
  20.     public void setAddr(String addr) {  
  21.         this.addr = addr;  
  22.     }  
  23. }  

 

Student.java:

Java代碼    收藏代碼
  1. package com.iflytek.entity;  
  2.   
  3. /** 
  4.  * @author xdwang 
  5.  *  
  6.  * @ceate 2012-6-27 上午12:31:07 
  7.  *  
  8.  * @description Student實體 
  9.  *  
  10.  */  
  11. public class Student {  
  12.   
  13.     private String username;  
  14.     private int grade;  
  15.   
  16.     public Student() {  
  17.     }  
  18.   
  19.     public Student(String username, int grade) {  
  20.         this.username = username;  
  21.         this.grade = grade;  
  22.     }  
  23.   
  24.     public String getUsername() {  
  25.         return username;  
  26.     }  
  27.   
  28.     public void setUsername(String username) {  
  29.         this.username = username;  
  30.     }  
  31.   
  32.     public int getGrade() {  
  33.         return grade;  
  34.     }  
  35.   
  36.     public void setGrade(int grade) {  
  37.         this.grade = grade;  
  38.     }  
  39.   
  40.     @Override  
  41.     public String toString() {  
  42.         // 若是不重寫它的toString()方法的話,默認調用toString()將輸出【類型+@+內存地址的哈希值】  
  43.         return "{學生姓名:" + username + ",成績:" + grade + "}";  
  44.     }  
  45.   
  46. }  

 

User.java:

Java代碼    收藏代碼
  1. package com.iflytek.entity;  
  2.   
  3. /** 
  4.  *  
  5.  * @author xdwang 
  6.  *  
  7.  * @ceate 2012-6-27 上午12:29:11 
  8.  *  
  9.  * @description User實體 
  10.  *  
  11.  */  
  12. public class User {  
  13.     private String username;  
  14.     private String password;  
  15.     private Address address;  
  16.   
  17.     public String getUsername() {  
  18.         return username;  
  19.     }  
  20.   
  21.     public void setUsername(String username) {  
  22.         this.username = username;  
  23.     }  
  24.   
  25.     public String getPassword() {  
  26.         return password;  
  27.     }  
  28.   
  29.     public void setPassword(String password) {  
  30.         this.password = password;  
  31.     }  
  32.   
  33.     public Address getAddress() {  
  34.         return address;  
  35.     }  
  36.   
  37.     public void setAddress(Address address) {  
  38.         this.address = address;  
  39.     }  
  40.   
  41.     public String getVOMethod() {  
  42.         return "這是User類中的一個普通方法";  
  43.     }  
  44. }  
 

 

LoginAction.java:

Java代碼    收藏代碼
  1. package com.iflytek.action;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.HashSet;  
  6. import java.util.List;  
  7. import java.util.Map;  
  8. import java.util.Set;  
  9.   
  10. import org.apache.struts2.interceptor.RequestAware;  
  11. import org.apache.struts2.interceptor.SessionAware;  
  12.   
  13. import com.iflytek.entity.Student;  
  14. import com.iflytek.entity.User;  
  15. import com.opensymphony.xwork2.ActionSupport;  
  16.   
  17. /** 
  18.  * @author xdwang 
  19.  *  
  20.  * @ceate 2012-6-27 上午12:33:18 
  21.  *  
  22.  * @description 登錄Action 
  23.  *  
  24.  */  
  25. @SuppressWarnings("serial")  
  26. public class LoginAction extends ActionSupport implements RequestAware,  
  27.         SessionAware {  
  28.     private User user;  
  29.     private List<String> testList = new ArrayList<String>();  
  30.     private Set<String> testSet = new HashSet<String>();  
  31.     private Map<String, String> testMap = new HashMap<String, String>();  
  32.     private List<Student> stus = new ArrayList<Student>();  
  33.   
  34.     private Map<String, String> request;  
  35.     private Map<String, String> session;  
  36.   
  37.     public void setRequest(Map request) {  
  38.         this.request = request;  
  39.     }  
  40.   
  41.     public void setSession(Map session) {  
  42.         this.session = session;  
  43.     }  
  44.   
  45.     public static String getStatic() {  
  46.         return "這是LoginAction中的一個靜態方法";  
  47.     }  
  48.   
  49.     public String getCommon() {  
  50.         return "這是LoginAction中的一個普通方法";  
  51.     }  
  52.   
  53.     @Override  
  54.     public String execute() throws Exception {  
  55.         if (user.getUsername().trim().equalsIgnoreCase("xdwang")  
  56.                 && user.getPassword().equals("1111")) {  
  57.             testList.add("list11");  
  58.             testList.add("list22");  
  59.             testList.add("list33");  
  60.             testList.add("list44");  
  61.             testList.add("list55");  
  62.   
  63.             testSet.add("set11");  
  64.             testSet.add("set22");  
  65.             testSet.add("set33");  
  66.             testSet.add("set22");  
  67.             testSet.add("set11");  
  68.   
  69.             testMap.put("m11""map11");  
  70.             testMap.put("m22""map22");  
  71.             testMap.put("m33""map33");  
  72.             testMap.put("m44""map44");  
  73.             testMap.put("m55""map55");  
  74.   
  75.             stus.add(new Student("張三"88));  
  76.             stus.add(new Student("李四"77));  
  77.             stus.add(new Student("王五"66));  
  78.             stus.add(new Student("馬六"55));  
  79.   
  80.             request.put("req""這是經過OGNL中的#號獲取的request屬性範圍的值");  
  81.             session.put("ses""這是經過OGNL中的#號獲取的session屬性範圍的值");  
  82.             request.put("BB""這是經過OGNL中的#號獲取的request屬性範圍的BB");  
  83.             session.put("BB""這是經過OGNL中的#號獲取的session屬性範圍的BB");  
  84.             return SUCCESS;  
  85.         } else {  
  86.             return INPUT;  
  87.         }  
  88.     }  
  89.   
  90.     public User getUser() {  
  91.         return user;  
  92.     }  
  93.   
  94.     public void setUser(User user) {  
  95.         this.user = user;  
  96.     }  
  97.   
  98.     public List<String> getTestList() {  
  99.         return testList;  
  100.     }  
  101.   
  102.     public void setTestList(List<String> testList) {  
  103.         this.testList = testList;  
  104.     }  
  105.   
  106.     public Set<String> getTestSet() {  
  107.         return testSet;  
  108.     }  
  109.   
  110.     public void setTestSet(Set<String> testSet) {  
  111.         this.testSet = testSet;  
  112.     }  
  113.   
  114.     public Map<String, String> getTestMap() {  
  115.         return testMap;  
  116.     }  
  117.   
  118.     public void setTestMap(Map<String, String> testMap) {  
  119.         this.testMap = testMap;  
  120.     }  
  121.   
  122.     public List<Student> getStus() {  
  123.         return stus;  
  124.     }  
  125.   
  126.     public void setStus(List<Student> stus) {  
  127.         this.stus = stus;  
  128.     }  
  129.   
  130. }  

 

login.jsp:

Jsp代碼    收藏代碼
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  4. <html>  
  5. <head>  
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  7. <meta http-equiv="pragma" content="no-cache">  
  8. <meta http-equiv="cache-control" content="no-cache">  
  9. <meta http-equiv="expires" content="0">  
  10. <title>OGNL Demo</title>  
  11. </head>  
  12. <body>  
  13.     <h1>這是測試OGNL使用的登陸頁面</h1>  
  14.     <h3>  
  15.         <font color="red">提示:</font>程序設定的用戶名和密碼各爲<font color="blue"><strong>xdwang</strong></font>和<font  
  16.             color="blue"><strong>1111</strong></font>  
  17.     </h3>  
  18.     <h3>  
  19.         <font color="red">注意:</font>用戶名和密碼不正確時將停留在頁面不動  
  20.     </h3>  
  21.     <form action="<%=request.getContextPath()%>/login.action" method="POST">  
  22.         <%--這裏user.username匹配的是LoginAction中的引用類型user裏面的username屬性--%>  
  23.         <%--查看標籤庫說明的話,就知道name中指定的是對象。這裏它不是字符串,而是OGNL表達式--%>  
  24.         姓名:<input type="text" name="user.username"><br> 密碼:<input  
  25.             type="text" name="user.password"><br> 地址:<input  
  26.             type="text" name="user.address.addr"><br> <input  
  27.             type="submit" value="測試OGNL的輸出">  
  28.     </form>  
  29. </body>  
  30. </html>  

 

loginSuc.jsp:

Jsp代碼    收藏代碼
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>  
  3. <%@ taglib prefix="s" uri="/struts-tags"%>  
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  5. <html>  
  6. <head>  
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  8. <meta http-equiv="pragma" content="no-cache">  
  9. <meta http-equiv="cache-control" content="no-cache">  
  10. <meta http-equiv="expires" content="0">  
  11. <title>OGNL Demo</title>  
  12. </head>  
  13. <body>  
  14.     <h1>這是使用OGNL輸出的結果頁面</h1>  
  15.     <table border="9">  
  16.         <tr>  
  17.             <td align="right">獲取姓名屬性:</td>  
  18.             <td align="left"><s:property value="user.username" /></td>  
  19.             <%-- 另外還有兩種寫法也是能夠正常輸出值棧中對象的普通屬性的 --%>  
  20.             <%-- <s:property value="user['username']"/> --%>  
  21.             <%-- <s:property value="user[/"username/"]"/> --%>  
  22.             <%-- 可是若是寫成下面這種形式的話,就什麼都不會輸出了 --%>  
  23.             <%-- <s:property value="user[username]"/> --%>  
  24.         </tr>  
  25.         <tr>  
  26.             <td align="right">獲取地址屬性:</td>  
  27.             <td align="left"><s:property value="user.address.addr" /></td>  
  28.         </tr>  
  29.         <tr>  
  30.             <td align="right">調用值棧中的對象的普通方法:</td>  
  31.             <td align="left"><s:property value="user.getVOMethod()" /></td>  
  32.         </tr>  
  33.         <tr>  
  34.             <td align="right">調用值棧中Action的普通方法:</td>  
  35.             <td align="left"><s:property value="getCommon()" /></td>  
  36.         </tr>  
  37.     </table>  
  38.     <hr />  
  39.     <table border="9">  
  40.         <tr>  
  41.             <td align="right">獲取普通類的靜態屬性:</td>  
  42.             <td align="left"><s:property value="@com.iflytek.entity.Address@TIPS" /></td>  
  43.         </tr>  
  44.         <tr>  
  45.             <td align="right">訪問普通類的構造方法:</td>  
  46.             <td align="left"><s:property  
  47.                     value="new com.iflytek.entity.Student('xdwang',23).username" /></td>  
  48.         </tr>  
  49.         <tr>  
  50.             <td align="right">調用Action中的靜態方法:</td>  
  51.             <td align="left"><s:property value="@com.iflytek.action.LoginAction@getStatic()" /></td>  
  52.         </tr>  
  53.         <tr>  
  54.             <td align="right">調用JDK中的類的靜態方法:</td>  
  55.             <td align="left"><s:property  
  56.                     value="@java.util.Calendar@getInstance().time" /></td>  
  57.         </tr>  
  58.         <tr>  
  59.             <td align="right">調用JDK中的類的靜態方法:</td>  
  60.             <td align="left"><s:property  
  61.                     value="@java.lang.Math@floor(46.58)" /></td>  
  62.         </tr>  
  63.         <tr>  
  64.             <td align="right">調用JDK中的類的靜態方法:</td>  
  65.             <td align="left"><s:property value="@@floor(46.58)" /></td>  
  66.         </tr>  
  67.     </table>  
  68.     <hr />  
  69.     <table border="9">  
  70.         <tr>  
  71.             <td align="right">獲取List中的全部元素:</td>  
  72.             <td align="left"><s:property value="testList" /></td>  
  73.         </tr>  
  74.         <tr>  
  75.             <td align="right">獲取Set中的全部元素:</td>  
  76.             <td align="left"><s:property value="testSet" /></td>  
  77.         </tr>  
  78.         <tr>  
  79.             <td align="right">獲取Map中的全部元素:</td>  
  80.             <td align="left"><s:property value="testMap" /></td>  
  81.         </tr>  
  82.         <tr>  
  83.             <td align="right">獲取Map中的某個m22元素:</td>  
  84.             <td align="left"><s:property value="testMap['m22']" /></td>  
  85.             <%-- 另外還有兩種寫法也是能夠正常獲取Map中的某個具體元素的 --%>  
  86.             <%-- <s:property value="testMap.m22"/> --%>  
  87.             <%-- <s:property value="testMap[/"m22/"]"/> --%>  
  88.         </tr>  
  89.         <tr>  
  90.             <td align="right">獲取Set中的某個元素:</td>  
  91.             <%-- 因爲Set中的元素是無順序的,因此不能使用下標獲取數據,因此這裏什麼也得不到 --%>  
  92.             <td align="left"><s:property value="testSet[2]" /></td>  
  93.         </tr>  
  94.         <tr>  
  95.             <td align="right">獲取List中的某個元素:</td>  
  96.             <td align="left"><s:property value="testList[2]" /></td>  
  97.         </tr>  
  98.     </table>  
  99.     <hr />  
  100.     <table border="9">  
  101.         <tr>  
  102.             <td align="right">獲取List的大小:</td>  
  103.             <td align="left"><s:property value="testList.size" /></td>  
  104.         </tr>  
  105.         <tr>  
  106.             <td align="right">獲取Set的大小:</td>  
  107.             <td align="left"><s:property value="testSet.size" /></td>  
  108.         </tr>  
  109.         <tr>  
  110.             <td align="right">獲取Map的大小:</td>  
  111.             <td align="left"><s:property value="testMap.size" /></td>  
  112.         </tr>  
  113.         <tr>  
  114.             <td align="right">獲取Map中全部的鍵:</td>  
  115.             <td align="left"><s:property value="testMap.keys" /></td>  
  116.         </tr>  
  117.         <tr>  
  118.             <td align="right">獲取Map中全部的值:</td>  
  119.             <td align="left"><s:property value="testMap.values" /></td>  
  120.         </tr>  
  121.         <tr>  
  122.             <td align="right">Lambda計算4的階乘:</td>  
  123.             <td align="left"><s:property  
  124.                     value="#f= :[#this==1?1 : #this*#f(#this-1)],#f(4)" /></td>  
  125.         </tr>  
  126.     </table>  
  127.     <hr />  
  128.     <table border="9">  
  129.         <tr>  
  130.             <td align="right">獲取List中的全部對象:</td>  
  131.             <td align="left"><s:property value="stus" /></td>  
  132.         </tr>  
  133.         <tr>  
  134.             <td align="right">利用投影獲取List中對象的名字:</td>  
  135.             <td align="left"><s:property value="stus.{username}" /></td>  
  136.         </tr>  
  137.         <tr>  
  138.             <td align="right">利用投影獲取List中第二個對象的名字:</td>  
  139.             <%-- 使用<s:property value="stus[1].{username}"/>獲取到的值爲:[李四] --%>  
  140.             <%-- 兩者的區別在於:後者比前者多了一箇中括號 --%>  
  141.             <td align="left"><s:property value="stus.{username}[1]" /> <s:property  
  142.                     value="stus[1].{username}" /></td>  
  143.         </tr>  
  144.         <tr>  
  145.             <td align="right">利用選擇獲取List中成績及格的全部對象:</td>  
  146.             <td align="left"><s:property value="stus.{?#this.grade>=60}" /></td>  
  147.         </tr>  
  148.         <tr>  
  149.             <td align="right">利用選擇獲取List中成績及格的第一個對象:</td>  
  150.             <td align="left"><s:property value="stus.{^#this.grade>=60}" /></td>  
  151.         </tr>  
  152.         <tr>  
  153.             <td align="right">利用選擇獲取List中成績及格的最後一個對象:</td>  
  154.             <td align="left"><s:property value="stus.{$#this.grade>=60}" /></td>  
  155.         </tr>  
  156.     </table>  
  157.     <hr />  
  158.     <table border="9">  
  159.         <tr>  
  160.             <td align="right">利用選擇獲取List中成績及格的全部對象的名字:</td>  
  161.             <td align="left"><s:property  
  162.                     value="stus.{?#this.grade>=60}.{username}" /></td>  
  163.         </tr>  
  164.         <tr>  
  165.             <td align="right">利用選擇獲取List中成績及格的第二個對象的名字:</td>  
  166.             <td align="left"><s:property  
  167.                     value="stus.{?#this.grade>=60}.{username}[1]" /></td>  
  168.         </tr>  
  169.         <tr>  
  170.             <td align="right">利用選擇獲取List中成績及格的第一個對象的名字:</td>  
  171.             <td align="left"><s:property  
  172.                     value="stus.{^#this.grade>=60}.{username}" /></td>  
  173.         </tr>  
  174.         <tr>  
  175.             <td align="right">利用選擇獲取List中成績及格的最後一個對象的名字:</td>  
  176.             <td align="left"><s:property  
  177.                     value="stus.{$#this.grade>=60}.{username}" /></td>  
  178.         </tr>  
  179.         <tr>  
  180.             <td align="right">利用選擇獲取List中成績及格的第一個對象而後求大小:</td>  
  181.             <td align="left"><s:property  
  182.                     value="stus.{^#this.grade>=60}.{username}.size" /></td>  
  183.         </tr>  
  184.     </table>  
  185.     <hr />  
  186.     <table border="9">  
  187.         <tr>  
  188.             <td align="right">利用OGNL中的#號獲取attr中的屬性:</td>  
  189.             <td align="left"><s:property value="#attr.BB" /></td>  
  190.         </tr>  
  191.         <tr>  
  192.             <td align="right">利用OGNL中的#號獲取request範圍中的屬性:</td>  
  193.             <td align="left"><s:property value="#request.req" /></td>  
  194.         </tr>  
  195.         <tr>  
  196.             <td align="right">利用OGNL中的#號獲取session範圍中的屬性:</td>  
  197.             <td align="left"><s:property value="#session.ses" /></td>  
  198.         </tr>  
  199.         <tr>  
  200.             <td align="right">利用OGNL中的#號獲取Paraments對象的屬性:</td>  
  201.             <td align="left"><s:property value="#parameters.netname" /></td>  
  202.         </tr>  
  203.         <tr>  
  204.             <td align="right">使用&#60;&#37;=request.getParameter&#40;""&#41;&#37;&#62;或者&#36;&#123;param.name&#125;獲取連接參數值:</td>  
  205.             <td align="left">${param.netname} <%=request.getParameter("netname")%>  
  206.             </td>  
  207.         </tr>  
  208.         <tr>  
  209.             <td align="right">查看值棧中的信息:</td>  
  210.             <td align="left"><s:debug /></td>  
  211.         </tr>  
  212.     </table>  
  213. </body>  
  214. </html>  
相關文章
相關標籤/搜索