<?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">
<!-- 定義了該xml文檔語法的位置 -->
<struts>
<!-- 常量,這個常量改爲true表示處於開發模式,所有在這個xml的修改可以馬上獲得反饋 -->
<constant name="struts.devMode" value="true" />
<!-- pacakge用於處理重名 -->
<!--
namespace對應訪問路徑,
可以“”和“/”表示所有作用(無論前面的地址到底是啥,囊括了其他namespace處理不了的所有action),
可以“/XX/YY”,訪問的時候指定路徑即可
-->
<package name="fuck" namespace="/FFFF" extends="struts-default">
<!-- 這裏就是訪問/fuck.action,可以化簡爲/fuck -->
<action name="fuck">
<!-- 不寫名字的result默認就是success -->
<result>/hello.jsp</result>
</action>
</package>
<!-- Action -->
<package name="test" namespace="/path" extends="struts-default">
<!-- class屬性制定之後訪問該類中的execute方法,返回值只要是success就執行跳轉 -->
<!-- 如果不配置class地址,則默認執行ActionSupport -->
<action name="test" class="com.test.Test">
<result name="success">/test.jsp</result>
</action>
</package>
<!-- 動態方法調用 -->
<package name="user" namespace="/user" extends="struts-default">
<!-- method參數指定了目標類中要執行的方法,如果沒有則默認執行execute() -->
<action name="userAdd" class="com.test.UserAction" method="add">
<result name="success">/add_success.jsp</result>
</action>
<!--
即使不填method參數,也可以在訪問的時候指定“/XXX/user/user!add”或者“user!add.action”
這就是DMI(動態方法調用)
-->
<action name="user" class="com.test.UserAction">
<result name="success">/add_success.jsp</result>
</action>
</package>
<!-- 通配符 -->
<package name="wild" namespace="/wild" extends="struts-default">
<!-- 如果有多個通配符都可以匹配,首先匹配最精確的(“*”最少的),精確度同樣的時候排位靠前的匹配 -->
<!--
name上面可以使用“*”作爲通配符使用,
出現一個“*”之後在action剩餘部分可以使用{1}{2}...指定第一第二...個“*”所傳輸的內容
這樣可以不但確定使用的方法,還可以確定結果頁面
-->
<action name="student*" class="com.test.StudentAction" method="{1}">
<result name="success">/studentfuck.jsp</result>
</action>
<!--
約定優於配置,定製好“約定”!在同一個項目組之中必須要使用同一種方法名等等等
可以大大縮減配置文件的長度
-->
<action name="*_*" class="com.test.{1}Action" method="{2}">
<result name="success">/{1}{2}.jsp</result>
</action>
</package>
<!-- 接收參數 -->
<package name="para" namespace="/para" extends="struts-default">
<!--
訪問的時候在URL後面增加屬性值,可以有幾種方法獲取
1、Action屬性接收參數:
偶爾用
在action類裏面直接設置私有參數並且設置setter、getter(匹配的是set、get後面的字符)
struts會自動設置參數,類型轉換都自動完成(要注意合法性)
/para/setPara?num=1234&name=Jack
(常用)2、DomainModel接收參數:
用得最多
在action裏面放一個對象,URL上直接寫對象名.對象屬性即可(匹配的依然是各自的set和get後面的字符)
適用於參數比較多的時候,可以直接使用一個域模型包裝起來
/para/setPara?user.age=12&user.name=Jack
注意:如果傳入的參數比需要的參數要多,那麼:
a、直接傳action屬性
b、使用vo(值對象),do(數據對象),dto(數據傳輸對象)
臨時接收對象作爲數據傳輸之用,之後在自己根據dto生成一個真正需要的對象
3、ModelDriven接收參數:
不常用
Action類實現ModelDriven接口,實現裏面的getModel(),
可以直接不需要對象.屬性,但是對象就需要自己new了
也即可以直接使用/para/setPara?num=1234&name=Jack,但事實上action裏面放的是一個user對象
-->
<action name="setPara" class="com.test.ParaAction" method="add">
<result name="success">/hello.jsp</result>
</action>
<!--
中文問題:
1、儘量post,少用get
2、默認的配置可以在struts包裏面的proprits文件裏面看到
-->
<!-- constant name="struts.i18n.encoding" value="UTF-8" /-->
</package>
<!-- 參數校驗,數值傳遞後往前 -->
<package name="check" namespace="/check" extends="struts-default">
<action name="checkPara" class="com.test.ParaCheckAction">
<result name="success">/hello.jsp</result>
<!-- 後臺和前臺通信的方法之一(後臺傳給前臺) -->
<!--
·校驗出錯的時候可以將出錯信息放在struts之中,在頁面可以拿出來顯示
在return ERROR之前寫入:this.addFieldError("user", "user is null!!");
可以針對同一個名字添加多個errorMessage
可以再頁面使用<s:fielderror fieldName="user"/>這種形式獲得
但是這樣使用的情況不多,因爲或強制加載默認的css,難看
更常用的是使用<s:property value="errors.user[0]"/>可以直接取得之前放入的字符串
-->
<!--
觀察struts的運行情況:<s:debug></s:debug>
標籤<s:property value="errors.user[0]"/>
errors(map),errors.user(array),errors.user[0](value)
專門用於獲取debug中Value Stack以及Stack Context裏面的屬性
Stack裏面存儲着這個action的所有屬性
-->
<result name="error">/error.jsp</result>
</action>
</package>
<!-- 數值傳遞前往後,獲取Map類型的request,session,application(Map類型)
HttpServletRequest,HttpSession,ServletContext -->
<package name="getWebElement" namespace="/webElement" extends="struts-default">
<action name="getEle*" class="com.test.WebElementAction{1}" method="getEle">
<!--
1、依賴於容器(struts)
在action中直接訪問:
Map request = (Map)ActionContext.getContext().get("request");
Map session = ActionContext.getContext().getSession();
Map application = ActionContext.getContext().getApplication();
後臺往裏面放東西之後:
request.put("r1", "r111111");
session.put("r2", "r222222");
application.put("r3", "r3333333");
前臺可以通過struts標籤獲取到,兩個都可以:
<s:property value="#request.r1"/>
默認的jsp方式:<%=request.getAttribute("r1") %><br>
(最常用) 2、控制反轉,依賴注入
依賴注入:我就有隻一個setter,找其他人來幫忙給我個對象
控制反轉:原來是我自己新建的值,現在是某個中介幫忙傳入給我的
實現接口 RequestAware,SessionAware,ApplicationAware
分別實現旗下的一個方法,將傳入的request,session,application複製即可
這樣獲取到的也是Map<String, Object>類型的
3、依賴於容器
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = request.getSession();
ServletContext application = session.getServletContext();
4、控制反轉,依賴注入
實現ServletRequestAware接口並實現其中的方法
-->
<result name="success">/getEle.jsp</result>
<result name="error">/error.jsp</result>
</action>
</package>
<!-- 默認action -->
<package name="default" namespace="/default" extends="struts-default">
<!-- 添加該語句之後,該namespace下所有找不到目的地的action都會被引導到這個action下 -->
<!-- 在這個配置裏,由於namespace設置成了任意路徑"/",所以任何找不着北的訪問都會被引導到index -->
<default-action-ref name="index"></default-action-ref>
<action name="index">
<result>/index.jsp</result>
</action>
</package>
<!-- result -->
<package name="result" namespace="/result" extends="struts-default">
<!-- 全局結果集,這個package內的所有action都可以使用 -->
<!--
如果想要讀取其他包裏面的結果集,則可以讓那個包繼承這個包
只需要配置屬性extends繼承包就可以了
-->
<!-- 特別注意,package內對個元素的排序有着嚴格要求,action要放在最後 -->
<global-results>
<result name="allCanUser">hello.jsp</result>
</global-results>
<action name="index">
<!--
設置result的各種類型:
dispatcher(默認)服務器端跳轉
redirect 客戶端跳轉
chain 服務器端跳轉到一個action,前兩個只能跳轉到頁面,訪問action的時候不要加斜槓
redirectAction 客戶端跳轉到action
剩下還有幾種不需要管
-->
<result type="redirect">/index.jsp</result>
</action>
<action name="index2">
<result type="chain">index</result>
</action>
<!-- 使用chain的時候,如果目標action在其他package裏面,則可以在中間指定namespace以及actionName-->
<action name="index3">
<result type="chain">
<param name="namespace">/webElement</param>
<param name="actionName">getEle1</param>
</result>
</action>
</package>
<package name="result_son" namespace="/result_son" extends="result">
</package>
<!-- 特別的result -->
<package name="specresult" namespace="/spec" extends="struts-default">
<!--
比較少用
動態結果集,在這裏使用action裏面的變量,相當於從stack裏面獲取值
這個是專門用在配置文件裏面的OGNL表達式
-->
<action name="res" class="com.test.ResultAction" method="execute">
<result>${asdf}</result>
</action>
<!--
只有在redirect的時候使用
帶參數的結果集,從一個action向其他頁面跳轉的時候,想辦法帶上一些參數
1、一次request只有一個值棧,所以各個action使用服務器端forward的時候參數一直保留
2、使用客戶端跳轉的時候,參數無法保留,可以用這種方法傳參
-->
<action name="res2" class="com.test.ResultAction" method="execute2">
<result type="redirect">/add_success.jsp?t=${asdf}</result>
</action>
</package>
<!-- OGNL: Object Graph Navigation Language 對象圖導航語言 -->
<package name="ognl" namespace="/ognl" extends="struts-default">
<!--
一個表達式:<s:property value="username"/>
OGNL表達式代表着value的雙引號之內的內容,至於前面的s:是標籤
action裏面的所有屬性、對象,只要是設定了getter和setter,就都可以在struts的值棧裏面看到
訪問靜態方法、靜態屬性之前必須在這裏設定
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
訪問時必須在OGNL語句的開頭加上“@”,連續兩個“@@”可以直接使用Math類的靜態方法
可以指定訪問某個類的某個構造方法,只要語法合適 new com.test.User('lalala')
-->
<action name="check" class="com.test.CheckOGNLAction">
<result>/ognl.jsp</result>
</action>
</package>
<!-- 設定允許訪問靜態方法 -->
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>
<!-- 包含其他的配置文件,可以分模塊開發 -->
<!--include file="out_struts.xml"/-->
</struts>
在頁面上OGNL的使用
<body>
<ol>
<h6>屬性訪問</h6>
-----普通屬性、對象訪問----------------------------------------------------------------<br>
<li>訪問值棧中的action的普通屬性:username = <s:property value="username"/> | password = <s:property value="password"/></li>
<li>訪問值棧中對象的普通屬性:user = <s:property value="user"/> | user.age:<s:property value="user.age"/></li>
<li>訪問值棧中對象的對象屬性:biguser = <s:property value="biguser"/> | biguser.user = <s:property value="biguser.user"/></li>
<li>訪問值棧中對象的普通方法:username.length() = <s:property value="username.length()"/></li>
<li>訪問值棧中action的普通方法:CheckOGNLAction.shout() = <s:property value="shout()"/></li>
-----靜態方法、屬性訪問----------------------------------------------------------------<br>
<li>訪問靜態方法:@com.test.Test.staticShout() = <s:property value="@com.test.Test@staticShout()"/></li>
<li>訪問靜態屬性:@com.test.Test.staticTestValue = <s:property value="@com.test.Test@staticTestValue"/></li>
<li>訪問Math類靜態方法:@@max(3,4) = <s:property value="@@max(3,4)"/></li>
-----構造器訪問------------------------------------------------------------------------<br>
<li>訪問指定的構造方法:new com.test.User(lalala) = <s:property value="new com.test.User('AAA')"/>|<s:property value="new com.test.User(\"BBB\")"/></li>
-----容器訪問--------------------------------------------------------------------------<br>
<li>訪問list、數組: = <s:property value="userList"/></li>
<li>訪問list、數組中某個屬性集合(組成新List): = <s:property value="userList.{name}"/></li>
<li>訪問list、數組中某個屬性集合的特定值: = <s:property value="userList.{name}[0]"/>| 更常用的:<s:property value="userList[0].name"/></li>
<li>訪問Set: = <s:property value="userSet"/></li>
<li>訪問Set中某個元素(沒有意義): = <s:property value="userSet[0]"/></li>
<li>訪問Map: = <s:property value="userMap"/></li>
<li>訪問Map中的某個元素: = <s:property value="userMap.map1"/>|<s:property value="userMap['map2']"/>|<s:property value="userMap[\"map4\"]"/></li>
<li>訪問Map中所有的key: = <s:property value="userMap.keys"/></li>
<li>訪問Map中所有的value: = <s:property value="userMap.values"/></li>
<li>訪問容器的大小: = <s:property value="userMap.size()"/></li>
-----投影(過濾)----------------------------------------------------------------------<br>
<li>投影(符合條件的集合): = <s:property value="userList.{?#this.age>20}"/></li>
<li>投影(符合條件的第一個): = <s:property value="userList.{^#this.age>20}"/></li>
<li>投影(符合條件的最後一個): = <s:property value="userList.{$#this.age>20}"/></li>
<li>投影(結果是否爲空): = <s:property value="userList.{$#this.age>20} == null"/></li>
-----方括號訪問----------------------------------------------------------------------<br>
<li>【】值棧從上往下第一個對象的“位置”,進行服務器端跳轉的話會有多個Action: = <s:property value="[0]"/></li>
<h6>標籤</h6>
-----property----------------------------------------------------------------------<br>
<li>property: <s:property value="username"/> </li>
<li>property 取值爲字符串(默認以對象對待): <s:property value="'username'"/> </li>
<li>property 設定默認值: <s:property value="admin" default="管理員"/> </li>
<li>property 設定HTML(true則不解析成HTML): <s:property value="'<hr/>'" escape="true"/> </li>
-----set----------------------------------------------------------------------<br>
<li>set 設定adminName值(默認爲request 和 ActionContext): <s:set var="adminName1" value="'username'" /> | <s:set var="adminName2" value="username" /></li>
<li>set 從request取值: <s:property value="#request.adminName1" /> | <s:property value="#request.adminName2" /></li>
<li>set 從ActionContext取值: <s:property value="#adminName1" /> | <s:property value="#adminName2" /></li>
<li>set 設定範圍: <s:set name="adminPassword" value="password" scope="page"/></li>
<li>set 從相應範圍取值: <%=pageContext.getAttribute("adminPassword") %></li>
<li>set 設定var,範圍爲ActionContext: <s:set var="adminPassword" value="password" scope="session"/></li>
<li>set 使用#取值: <s:property value="#adminPassword"/> </li>
<li>set 從相應範圍取值: <s:property value="#session.adminPassword"/> </li>
-----iterator----------------------------------------------------------------------<br>
<li>
遍歷集合:<br>
<s:iterator value="{1,2,3,4,5,2,3,4}">
<s:property/> |
</s:iterator>
</li>
<li>自定義變量:<br />
<s:iterator value="{'aaa', 'bbb', 'ccc'}" var="x">
<s:property value="#x"/> | <s:property value="#x.toUpperCase()"/>
</s:iterator>
</li>
<li>使用status:<br />
<s:iterator value="{'aaa', 'bbb', 'ccc'}" status="status">
<s:property/> |
遍歷過的元素總數:<s:property value="#status.count"/> |
遍歷過的元素索引:<s:property value="#status.index"/> |
當前是偶數?:<s:property value="#status.even"/> |
當前是奇數?:<s:property value="#status.odd"/> |
是第一個元素嗎?:<s:property value="#status.first"/> |
是最後一個元素嗎?:<s:property value="#status.last"/>
<br />
</s:iterator>
</li>
<li>遍歷map:<br />
<s:iterator value="#{1:'a', 2:'b', 3:'c'}" >
<s:property value="key"/> | <s:property value="value"/> <br />
</s:iterator>
</li>
<li>使用自定義變量遍歷Map:<br />
<s:iterator value="#{1:'a', 2:'b', 3:'c'}" var="x">
<s:property value="#x.key"/> | <s:property value="#x.value"/> <br />
</s:iterator>
</li>
<li>遍歷action裏的list:<br />
<s:iterator value="userList" var="x">
<s:property value="#x"/> |
</s:iterator>
</li>
<li>使用自定義變量遍歷Map:<br />
<s:iterator value="userMap" var="x">
<s:property value="#x.key"/> | <s:property value="#x.value"/> <br />
</s:iterator>
</li>
</ol>
調出debug頁面
<s:debug></s:debug>
</body>