Java Struts

<?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>




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