一、Struts2 主要幾句話:
1、 Struts2 是由webwork2發展來的而非Struts1,相比Struts1,Struts2編碼規范跟類似與webwork2
2、Struts2 非侵入式設計、Struts1屬于侵入式設計
3、Struts1與ServletAPI、strutsAPI緊密耦合;Struts1則不
4、Struts2 利用攔截器進行AOP編程,實現如權限攔截功能
5、Struts2 提供了類型轉換器
6、Struts2 提供多種表現層技術,如JSP/Freemarker/Velocity等
7、Struts2 的輸入驗證可以對指定方法進行驗證,解決Struts1之痛
8、Struts2 提供了全局范圍、包范圍和Action范圍的國際化資源文件管理實現
9、Struts2 核心組件:Action,ValueStack,Result,Interceptor
二、Struts2 需要的最少jar:
Struts-core-2.xx.jar
Xwork-2.xx.jar
Ognl-2.6.x.jar 對象圖導航語言(Object Graph Navigation Language),Struts2通過其讀寫對象屬性
Freemarker-2.3.x.jar
Commons-logging.jar
Commons-fileupload.jar
切勿全選所以jar,否則你會很痛苦,Struts2提供其他框架的支持,所以依賴其他jar、一些配置文件。
三、環境搭建三部曲:
1. 找到開發Struts2應用需要使用的jar文件
2. 編寫Struts2配置文件
3. 在web.xml中加入Struts2MVC框架啟動配置
附:2.1.8版本的配置
<!-- 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>
四、Struts.xml配置文件中包的介紹
<package name="default" namespace="/test" extends="struts-default">
<action name="index" class=”cn.itcast.action.HelloWorldAction” methed=”execute”>
<result name="succcess">/page/hello.jsp</result>
</action>
</package>
管理一組業務功能相關的action,在實際應用中把一組應用功能相關的action放在一個包下
1.name必須,其他包要繼承該包,必須經過該屬性進行引用
2.namespace定義該包的命名空間,命名空間做為訪問該包下action路徑的一部分,如上action訪問路徑為:/test/index.action
3. extends 默認繼承了struts-default包,可使這個包下面默認應用了struts2一些新功能,如攔截器等
4.abstract 當 abstract=”true” 則該包內不能有action
五、Struts2里Action名稱的搜索順序
1. 獲取請求的URL路徑,如下:
http://localhost:8080/struts2/path1/path2/path3/helloworld //配置可訪問
http://localhost:8080/struts2/path1/path2/path3/as/helloworld //也可訪問的
2. 首先尋找namespace為/path1/path2/path3的package,如果不存在這個package則執行步驟3;如果存在這個package,則在這個package中尋找名字為test的action,當在該package下尋找action時就會直接跑到默認namespace的package里面尋找action(默認的命名空間為空字符串””),如果在默認namespace的package里面還尋找不到action,頁面提示找不到action
3. 尋找namespace為/path1/path2的package,如果不存在這個package,則轉至步驟4;如果存在這個package,則在這個package中尋找名字為test的action,當在該package中尋找不到action時就會直接跑到默認namespace的package中尋找名字為test的action,在默認namespace的package里面還尋找不到該action,頁面提示找不到action
4. 尋找namespace為/path1的package,如果不存在這個package則執行步驟5;如果存在這個package,則在這個package中尋找名字為test的action,當在該package中尋找不到action時就會直接跑到默認的namespace的package里賣弄去尋找名字為test的action,在默認namespace(<package name="default" extends="struts-default">)的package里面還尋找不到該action,頁面提示不到action
5. 尋找namespace為/的package,如果存在這個package,則在這個package中尋找名字為test的action,當在package中尋找不得action或者不存在這個package時,都會去默認namespace的package里面尋找action,如果還找不到,頁面提示找不到action
六、Action配置中各項默認值
1. 如果沒有給action配置class,則默認的是ActionSupport
2. 如果沒有給action配置method,則默認的是execute方法
3. 如果沒有給result配置name,則默認的是success
例如:可以利用各種默認項的搭配,完成action轉發
Struts1:
<action path=”/control/employee/addUI” >
<!—Struts1的轉發 -->
<forward name=”addUI”>/WEB-INF/page/employeeAdd.jsp</forward>
<!—Struts1的重定向 -->
<!--
<forward name=”addUI” redirect=”true”>/WEB-INF/page/employeeAdd.jsp</forward>
-->
</action>
Struts2:
<action name=”addUI”>
<result>/WEB-INF/page/employeeAdd.jsp”</result>
</action>

同樣訪問http://localhost:8080/XX/addUI.action 就可訪問到employeeAdd.jsp
七、Struts2 中result常用的視圖轉發類型(dispatcher(默認)、redirect、redirectAction、plainText、chain)
1. dispatcher-轉發上面已經介紹了
(1)為缺省的result類型,一般情況下我們在struts.xml會這么寫:
<result name="success">/main.jsp</result>
以上寫法使用了兩個默認,其完整的寫法為:
<result name="success" type="dispatcher">
<param name="location">/maini.jsp</param>
</result>
第一個默認:type="dispatcher";第二個默認:設置的為location參數,location只能是頁面,不能是另一個action(可用type="chain"解決)。
(2)實現方式
從doExecute方法看出,有三個出口(finalLocation為要跳轉的地址):
pageContext.include(finalLocation);
dispatcher.forward(request, response); (dispatcher是根據finalLocation創建的)
dispatcher.include(request, response);
而我們知道,forward與include都是轉發到context內部的資源。
2.redirect-重定向
a).<action name="redirect">
<result type="redirect">/index.jsp</result>
</action>
b).ognl表達式,在struts.xml中獲取action中的變量
<action name="redirect">
<result type="redirect">
/index.jsp?username=${username}</result>
</action>
http://localhost:8080/struts2/redirect.action 將重定向到如下URL
http://localhost:8080/struts2/index.jsp?username=”action中定義的值”
傳中文時候請進行編碼:
username = URLEncoder.encode(“李顯武”, “UTF-8”);
注意用get方式傳的中文,在頁面顯示還需要解密:
URLDecoder.decode[new String(request.getParameter(“username”).getBytes(“ISO8859-1”), “UTF-8”]
注:action中要提供該變量的getter、setter方法
3. redirectAction-重定向到action(action在同一個包)
注: redirect和redirectAction兩種結果類型在使用上其實并沒有什么區別,只是寫法不同而已。
<action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute">
<result name="success">/WEB-INF/page/hello.jsp</result>
</action>
<action name="redirectAction">
<result type="redirectAction">helloworld</result>
</action>
當action不在同一個包時候
<action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute">
<result name="success">/WEB-INF/page/hello.jsp</result>
</action>
<action name="redirectAction">
<result type="redirectAction">
<param name=”actionName”>action名</param>
<param name=”namespace”>需要重定向的action所在的包</param>
</result>
</action>
4. plainText-顯示原始文件內容,例如:當我們需要原樣顯示jsp文件源代碼的時候,我們可以使用此類型
<action name=”plainText”>
<result name=”souce” type=”plainText”>
<param name=”location”>/xxx.jsp</param>
<param name=”charSet”>UTF-8</param><!—指定讀取文件的編碼 -->
</result>
</action>
5. chain-action鏈
(1)主要用于把相關的幾個action連接起來,共同完成一個功能,需要獲得上一個action中傳下來的值,只需要在下一個action中聲明同名的屬性
<action name="step1" class="test.Step1Action">
<result name="success" type="chain">step2.action</result>
</action>
<action name="step2" class="test.Step2Action">
<result name="success">finish.jsp</result>
</action>
(2)實現方式:
查看execute()方法,主要思想如下:
// 根據Action名稱finalActionName及要調用的方法finalMethodName來new一個代理對象proxy,并執行之
proxy = actionProxyFactory.createActionProxy(finalNamespace,
finalActionName, finalMethodName, extraContext);
proxy.execute();
(3)多個action間數據的傳遞
主要有兩種方式:
1、由于處于chain中的action屬于同一個http請求,共享一個ActionContext,故可以在上下文中獲取,在頁面上可以直接使用。手動獲取的方法如下:
HttpServletRequest request = ServletActionContext.getRequest();
String s=(String)request.getAttribute("propName");
2、實現ModelDriven接口
在Step1Action中,加入getModel:
public Object getModel() {
return message;
}
在Step2Action中,加入setModel:
public void setModel(Object o){
System.out.println("message is:"+o);
}
注意,setModel的調用先于execute()方法后于構造方法。
八、在Struts2中公用的視圖
<package ……>
<global-result>
<result name=”pub”>/public.jsp</result>
</global-result>
</package>
九、為Action屬性注入值
<action name=”list” class=”cn.itcast.action.HelloWorldAction”>
<param name=”savepath”>/images</param>
<result>/WEB-INF/page/message.jsp</result>
</action>
從配置文件將value植入action的屬性,再用EL表達式將action的屬性值顯示出來
注意變量的命名、getter、setter方法
十、指定Struts2處理的請求后綴
默認使用的是處理.action的請求,其實也可以通過常量”struts.action.extension”進行修改,如我們可以配置Struts2只處理以.do為后綴的請求路徑:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.action.extension" value="do"></constant>
</struts>
也可以指定處理多個后綴請求 value之間以”,”分開如: value=”do,action,jhtml”
十一、細說常量的配置
Struts2中常量可以在多個配置文件中配,建議在struts.xml中配置方式如下:
<struts>
<constant name=”struts.action.extension” value=”do”/>
</struts>
因為常量可以在多個配置文件中進行定義,所以我們需要了解struts2加載常量的搜索順序:
struts-default.xml
struts-plugin.xml
struts.xml
struts.properties
web.xml
如果在多個文件中配置了同一個常量,則后一個配置文件中的常量值將會覆蓋前面文件中配置的常量值