一、contextMap中的數據操作
1、存數據:
需要熟悉 ActionContext類
和 ValueStack接口
的 AP
I
。框架爲我們存數據。
1.1、利用 ActionContext 存數據
我們先看看 ActionContext.class 的源碼:
1.2、利用 ValueStack 存數據 a、如何獲取ValueStack呢?
b、ValueStack中的getRoot()方法。
c、CompoundRoot是什麼?
d、棧操作。 動作類中相應的代碼爲:
學生實體類代碼:
Struts Debug頁面查看數據:
2、取數據:用Struts2的標籤(OGNL表達式)在JSP上(用的最多)
使用OGNL表達式來去,struts2的OGNL表達式必須寫在struts2標籤中。
2.1、使用s:property取數據
a、取contextMap中的數據,需使用 #key
。
b、取contextMap裏面ValueStack中對象的屬性:直接寫屬性名
如果遇有對象的屬性的名稱相同(屬性名同名),可以通過OGNL表達式,選擇查找的起始位置。它會從指定起始位置逐個對象查找指定的屬性名稱,只要找到了,就不再繼續查找了。
特殊說明:當s:property不給定value屬性時,默認取棧頂對象。
OGNL的使用總結: 1.取根(root)中對象的屬性,不使用#。 2.取contextMap中key的值,要使用#。 2.2、ValueStack的其他方法 a、setValue方法
b、set方法
c、findValue方法:我們在jsp上調用的其實都是findValue
二、Struts2對EL的改變
1、Struts2中使用EL的問題
前提:
我們應該知道,如果我們在動作類中沒有往 值棧(根) 中放入數據的話,那麼我們的動作類對象默認是在值棧的棧頂。
問題:
我們放到動作類中的屬性和請求域中的屬性,使用EL表達式取出來了。但是放到應用域中的屬性,使用EL表達式沒取出來。
2、關於EL問題的分析
分析: 我們知道EL表達式是從四大域對象中依次查找屬性。搜索範圍是由小到大。 查找順序:pageScope --> requestScope --> sessionScope --> applicationScope 但是通過測試發現,程序搜索放到應用域中的name屬性,搜索完request範圍後就沒有繼續搜索了,原因是:在請求域中沒有找到的情況下,去ValueStack中查找了,返回了ValueStack中棧頂對象name屬性的值。 問題出現在這個request的包裝類上了,該包裝類對getAttribute方法進行了改寫,如下圖所示:
我們來看看這個包裝類的源碼:
3、Struts2中EL查找順序改變總結
EL表達式的查找順序:pageScope --> requestScope --> sessionScope --> applicationScope
Struts2對EL表達式查找順序的改變:pageScope --> requestScope --> valueStack(根中)
--> 剩餘的contextMap(小Map)
--> sessionScope --> applicationScope
4、OGNL的特殊說明
當我們不寫#號時,OGNL表達式會從值棧的棧頂開始找對應的屬性,如果沒有該屬性,再去contextMap中把value的值作爲key去查找對應的值。這個知道就行,我們開發中一般不這麼寫!
三、OGNL配合通用標籤的其他使用
1、iterator標籤(很重要)
2、OGNL投影(瞭解)
2.1、使用過濾條件投影 2.2、投影指定屬性 如下圖所示:
3、Struts2中 `#,$,%` 符號的使用(重要)
3.1、#
a、取contextMap中鍵key對應的值value時使用,例如:<s:property value="#name"/>
b、OGNL中創建Map對象時使用,例如:<s:radio list="#{'male':'男', 'female':'女'}"/>
3.2、$
a、在JSP中使用EL表達式時使用,例如:${name}
b、在xml配置文件中,編寫OGNL表達式時使用,例如:文件下載時,文件名編碼:
struts.xml --> ${@java.net.URLEncoder.encode(filename)}
3.3、%
在struts2中,有些標籤的value屬性取值就是一個OGNL表達式,例如:<s:property value="OGNL Expression"/>
還有一部分標籤,value屬性的取值就是普通字符串,例如:<s:textfield value="username"/>
,
如果想把一個普通的字符串強制看成是OGNL表達式,就需要使用 %{}
把字符串套起來。例如:<s:textfield value="%{username}"/>
。
當然在 <s:property value="%{OGNL Expression}"/>
也可以使用,但一般不會這麼用,因爲你兩次告訴我你是OGNL表達式,不是有病嗎!
4、Struts2中其他標籤的使用
4.1、set標籤
4.2、action標籤
4.3、if標籤,elseif標籤 else標籤
4.4、url和a標籤(很有用)
修改動作名稱的擴展名
四、Struts2的UI標籤和主題
1、Struts2中UI標籤的優勢
自動的數據回顯和錯誤提示功能 自帶的簡單樣式和排版
2、表單標籤的通用屬性
說明:UI標籤中value的取值一般都是字符串。 2.1、UI標籤的通用屬性
2.2、關於標籤checkboxlist的使用
2.3、UI標籤的小案例以及模型驅動的分析
3、UI標籤的模板(主題)
3.1、struts2中默認主題 默認主題的名稱是XHTML,都是在struts的默認屬性文件中定義着,該文件是:default.properties, 文件位置:\struts-2.3.15.3-all\struts-2.3.15.3\apps\struts2-blank\WEB-INF\lib\struts2-core-2.3.15.3\org\apache\struts2\default.properties
3.2、更改默認主題 a、更改表單某個元素的默認主題:使用的是表單元素的theme屬性。 b、更改表單所有主題:使用的是form標籤的theme屬性。 c、更改全站所有表單主題:是在struts.xml配置文件中,覆蓋原有主題的設置。 如下圖所示:
注意:當我們使用了simple主題後,我們需要 自己添加文本信息
。原來我們在jsp中怎麼寫,現在還怎麼寫。
例如: <s:textfield name="name" label="用戶名" /> 改寫爲: 用戶名:<s:textfield name="name" />
五、防止表單重複提交(使用攔截器)
1、回顧之前的解決辦法:
2、Struts2中的解決辦法:
2.1、使用重定向
遺留的問題:刷新頁面,再提交沒有問題,但是防不住後退,再提交。
2.2、表單上使用<s:token/>
生成令牌,再配合token攔截器
,在struts.xml中進行相關的配置
點擊後退再提交時,會提示:沒有一個invalid.token的結果視圖,如下圖所示:
那我們就配置一下這個invalid.token的結果視圖:
遺留的問題:此種解決方式,是產生了錯誤之後再去告知用戶,你錯了。
2.3、表單上使用<s:token/>
生成令牌,再配合tokenSession攔截器
,在struts.xml中進行相關的配置
該攔截器只會處理第一次請求,當重複提交請求時,不會再處理。