Struts2配置使用參數接收,轉發與重定向,多方法,ognl使用與值傳遞,struts標簽使用
本文檔包括了
Struts2配置使用參數接收,轉發與重定向,多方法,ognl使用與值傳遞,struts標簽使用
(1)首先加入jar包(最小jar組合)
(1) 在web.xml中註冊Struts2
這是一個前控制器作用是提供一個統一的入口,所有的請求都先經過前控制器就是這裏,然後由他在做進一步處理
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(2) 編寫後控制器Action類
編寫Action類需要一個無參構造函數,控制器方法名字任意,但不能帶參數,並且返回值類型必須是String
(3) 配置Action類編寫src/struts.xml
<?xml version="1.0"
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<!--
dtd:文件類型聲明,約束文件的標簽規格
Struts 配置文件,配置Action類
package:配置文件的包,將配置文件進行分包放置管理
name= "nyist" 包名,之後定義的每一個包,名字都不一樣就和類的包一樣
extends="struts-default" 繼承了
namespace :是Action的訪問前綴,即要訪問namespace 為“/a” 的包中的name為"hello" 的Action
http://localhost:8080/項目名/a/hello.action
作用:在namespace 的支持下,較徹底的將配置文件分模塊管理了
-->
<struts>
<package name="nyist" extends="struts-default" namespace="/a">
<!-- 配置Action
name ="hello" 等價於Servlet中的url-pattern
即在訪問的時候我們需要加入/hello 自己定義的
class ="com.nyist.action.HelloWorldaction" 即是Action的全限定名
method = "abc" 即method表示的是我們需要訪問該Action的abc此方法,因為方法是自定義的所以很大的空間命名,所以我們需要指定我們訪問的是那個方法
-->
<action name="hello" class="com.nyist.action.HelloWorldaction" method="abc">
<!--<result name="helloOK">
abc方法返回的值 helloOK,然後進行view視圖的調用,反義到index.jsp
-->
<result name="helloOK">/index.jsp</result>
</action>
</package>
</struts>
(4) 方法參數接收問題
Struts 框架集合了很好的參數接收問題。我們只需要在我們所要訪問的那個Action類中定義我們訪問時候使用的jsp文件中出現的我們需要傳遞的值的名稱例如
<input type="text" name="name"/> name這個屬性名稱。我們只需要在action類定義一個私有屬性,並進行get/set方法。然後struts就進行自我封裝。所以我們在本類取我們傳遞過來的值得時候就只需要訪問我們的私有屬性即可例如:
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
System.out.println(name+"===="+age+"====");
這樣就相當的簡單了,不需要我們使用HttpRequest 進行訪問了
List<對象>也行
Date等和基本屬性
(5) 轉發與重定向
<!--
dispatcher:請求轉發:type的默認值轉發到JSP
redirect : 重定向到JSP
redirectAction :重定向到Action
chain: 轉發到Action
-->
例如:
<result name="paramOK" type="dispatcher">/index.jsp</result>
註意:我們轉發或者跳轉到一個action中的時候,我們需要聲明,轉發或者跳轉action的位置,即namespace(包的namespace,註意/ 不能少)和name(你自己在定義那個action的時候的name)。但是如果跳轉雙方都在一個package中,那麽namespace可以省略,即默認是在當前包中跳轉例如:(原跳轉,和改良後的)(redirectAction 重定向到Action 和上面的轉發到Action中相似就是將chain 改為redirectAction 即可)
例如:
為了防止重復提交我們選取重定向(當action做的是增刪改的操作的時候我們需要使用重定向(redirectAction),當操作查詢的時候我們使用轉發(chain))
(6) 全局跳轉
全局跳轉:抽取一個package 中的重復的result(例如錯誤) 簡化配置,
:每個全局跳轉(<result>) 都是在當前的包中的所有的Action 之間共享的。註意:全局跳轉,只存在於一個包中,不存在不同包中的。全局跳轉需要放在action之前
例如:
<global-results>
<result name="">/error.jsp</result>
</global-results>
(8)Action 的創建模式:非單例模式,每個請求都獨享一個Action的實例對象
例如:UserAction{
}
請求一次:new UserAction()
再請求一次:new UserAction()
再再請求一次:new UserAction()
Servlet :單例模式
(9) Action的生命周期:一個請求,請求到來的時候創建,請求結束的時候就銷毀
(10)Action的創建方式:
1)public class ClassName{(pojo)建議使用
方法
}
2)public class ClassName extends ActionSupport{ (ActionSupport是Action的實現類是一個適配器)
方法
}
3) public class ClassName implements Action{
方法
}
註意:Action中的默認執行方法:
Public String execute(){
。。。。。。
Return 。。;
}
即如果配置中<action name=”XX” class =”XX”></action> 沒有定義method屬性,則默認執行execute 方法
(11)多方法控制
<!-- 多方法控制:
在一個Action中定義多個不同實現不同作用的方法,
然後進行在.xml 文件中進行配置,配置原則就是多個action 對應了多個方法class相同,
method 對應不同的方法名,已經之後的不同的方法返回值
-->
<!-- 靜態調用 -->
<!--
<action name="manyfuns" class="com.nyist.action.ManyFunction" method="fun1">
<result name="fun1">/fun1.jsp</result>
</action>
<action name="manyfuns1" class="com.nyist.action.ManyFunction" method="fun2">
<result name="fun2">/fun2.jsp</result>
</action>
<action name="manyfuns2" class="com.nyist.action.ManyFunction" method="fun3">
<result name="fun3">/fun3.jsp</result>
</action>
-->
<!--
動態調用:name="manyfuns_* 中*是通配符 ,匹配任意一個或者多個字符
/manyfuns_fun1
/manyfuns_fun2
/manyfuns_fun3
.......
method="{1}" 中的{1} 是一個占位符,此位置會填充【*】號當前匹配的位置
每個請求到來時* 都可以匹配到不同的內容
此時的url是:
http://localhost:8080/StrutsDemo/manyfuns_fun1(調用fun1)
http://localhost:8080/StrutsDemo/manyfuns_fun2(調用fun2)
http://localhost:8080/StrutsDemo/manyfuns_fun1(調用fun3)
-->
<action name="manyfuns_*" class="com.nyist.action.ManyFunction" method="{1}">
<result name="fun1">/fun1.jsp</result>
<result name="fun2">/fun2.jsp</result>
<result name="fun3">/fun3.jsp</result>
</action>
(12)(數據處理機制=ognl + 值棧 +struts標簽)
作用:
OGNL(對象圖導航語言)
:尋址,取值
:獨立的組件(ognl.jar)
: 取值來源:根(任何一個對象成為ognl的根對象)和上下文(任何一個Map都可以成為ognl的上下文)
: 為ognl指定【根對象】或【上下文】,之後ognl即可以從中取值
:從根對象取值語法
1》Ognl.getValue(‘屬性名’,下文, 根)
2》從根中取出其中的數組屬性中的值(可以通過強轉和屬性[index] 進行取出)
3》從根中取出其中對象屬性的屬性值是(可以通過強轉和對象屬性名.對象的屬性名)
如下面,addr是User的對象屬性,為city和id是對象屬性的類屬性
4》 如果取出的值是Map 可以通過【.key】獲取對應的value
: 從上下文取值
1》 從上下文中取值,通過【key】獲取對應的value(註意:從上下文取值的時ognl表達式要以#開頭)
2》 如果要取出的值是數組的話那麽就第一個參數就使用”#你存的key[index]”
String [] hobbys = new String[]{"111","222","333"};
map.put("hobby",hobbys);
String hobby1 = (String) Ognl.getValue("#hobby[0]", map,new Object());
String hobby2 = (String) Ognl.getValue("#hobby[2]", map,new Object());
3》 如果要取出的值是對象的話那麽第一個參數就使用”#存儲對象的名字 . 你要獲取的對象的屬性名”
例如:
User u = new User(1,"zhangsan");
map.put("usr", u);
Integer id = (Integer) Ognl.getValue("#usr.id",map,new Object());
String name = (String) Ognl.getValue("#usr.name", map, new Object());
System.out.println(id + "===" + name);
4》 如果要取出的值是對象集合的話那麽分為三種集合Map集合那麽在取值的時候就可以第一個參數使用”#存儲集合的名字.key.對象屬性” ,如果是List集合的話那麽就是和數組相似“#存儲list集合的名子[索引].對象屬性”
ArrayList<User> list = new ArrayList<User>();
list.add(u);
list.add(u1);
map.put("list", list);
//List 集合取值
Integer id1 = (Integer) Ognl.getValue("#list[1].id", map,new Object());
System.out.println(id1);
5》 升級
調用取出數據類型中的所有的公開的方法
Integer n = (Integer)Ognl.getValue("#usr.name.length()", map, new Object());
運算(算術運算,,邏輯運算)
賦值
6》 setValue() 設置
=====================================================
值棧:struts 提供的一個域,用於存儲數據(傳值的媒介實現Action到jsp的數據傳輸,通信)
1》 在Action中向值棧存入數據
*需要OGNL找到對應位置,將數據存入
2》 在JSP中從值棧中獲取數據
*需要OGNL找到對應位置,將數據取出
3》 值棧:獲取方式
//獲取值棧對象ServletActionContext.getRequest();
ValueStack vs = ActionContext.getContext().getValueStack();
//向OGNL指向的位置取值
vs.findValue("OGNL");
//向OGNL 指向的位置存值
vs.setValue("ognl", );
vs.findValue(“#request.name”) //request.getAttribate(“name”)
vs.findValue(“#session.age”) // session.getAttribute(‘age’)
vs.setValue(“#request.age”,20);//request.setAttribute(“age”,20)
vs.setValue(“#session.name”,”zhang”),//session.setAttribute(“name”,”zhang”);
4》 值棧的內部存儲結構(Context 區域)
l Context 區域:本質是MAP
Key value
“request” mapr ===》等價於request作用於的底層的Map
“session” Maps ===》等價於session作用於的底層的Map
“application” Mapa ===》等價於application(servletContext)的作用域
l 等價: 數據嚴格同步
l 通過Context區域,可以統一的通過ValueStack操作三大作用於(request,session,application);等價的findValue(),setValue()函數進行上下文取值和設置
l
5》 實際案例
Action—>JSP
Action 存數據
Struts處理(使用的是重定向到JSP)
JSP取值(使用Struts標簽)
6》 值棧的內部存儲結構(Root區域)
l Root區域:本質上ArrayList,具有棧(Stack)的特點
1》 root區域中【存放當前請求的Action實例對象和s標簽遍歷時候的臨時值】
2》 root 區域中的元素為OGNL的根對象
3》 即當前的Action實例對象為OGNL的根對象
4》 由於本對象就是OGNL的根對象,那麽在賦值的時候很方便,直接進行this.屬性=你傳遞過來的值
例如:下面使用的轉發到jsp中,所以我們不需要使用session進設置在JSP中使用
註意:
通過Root區域,Struts2提供了全新的數據傳輸介質:根對象(Action), 但是由於根對象的生命周期僅為一個請求,所以通過根對象進行傳值 的話只能使用轉發。不能使用跳轉
根對象基本代替了請求作用域(request)去完成一個請求內部的數據 傳遞(Action——>JSP)
l
7》 Struts標簽(jsp使用時需要導入庫文件<[email protected] uri="/struts-tags" prefix="s"%> 這樣才能使用Struts的標簽)
l 獲取數據(取單值)
<s:property value="OGNL"/>(OGNL表示的是action轉入到該jsp頁面是創建的名稱例如:
或者是Root區域的特殊實現
比如第一個的結果jsp中取值就是
第二個取值就是)
l 分支判斷 (<s:elseif test=""></s:elseif> <s:else></s:else> )
實例:
l 遍歷(List集合)
(1)ROOT區域遍歷
<s:iterator value="#session.users">
<s:property value="id"/>
<s:property value="name"/>
<s:property value="age"/>
<br/>
</s:iterator>
註意:遍歷過程中,每次遍歷到的當前元素,都會被壓入棧的Root區域中,成為Root區域的棧頂元素,以及OGNL高級別
(2)上下文遍歷
<s:iterator value="#session.users" var="usr">
<s:property value="#usr.id"/>
<s:property value="#usr.name"/>
<s:property value="#usr.age"/>
<br/>
</s:iterator>
註意:遍歷過程中,每次都以【a】為key,以當前遍歷的元素為value存入Context中
(3) 相當於for
<s:iterator begin="1" end="10" var="i">
<s:property value="#i"/>
<br/>
</s:iterator>
(4)遍歷實例:
l 動態獲取項目名:(使用<s:url value=””/ > 標簽會自動補全項目名)
<a href="<s:url value=‘/index.jsp‘/>">跳轉</a>
<a href=‘<s:url value="/fun"></s:url>‘>飛</a>
8》
Struts2配置使用參數接收,轉發與重定向,多方法,ognl使用與值傳遞,struts標簽使用