Struts2總結


Struts2框架發展

Apache Struts 在 20005月由Craig McClanahan 發起,並於20017月發布了1.0版。

Struts一出現便大受歡迎,更成為了以后幾年內web 開發的實際標准。

Struts2Struts的下一代產品,是在WebWork的技術基礎上進行了合並。

 

Struts2是在WebWork2基礎發展而來的。主要是因為struts2有以下優點:

1 > 在軟件設計上Struts2沒有像struts1那樣跟Servlet APIstruts API有着緊密的耦合,Struts2的應用可以不依賴於Servlet APIstruts API。 Struts2的這種設計屬於無侵入式設計,而Struts1卻屬於侵入式設計。

2> Struts2提供了攔截器,利用攔截器可以進行AOP編程,實現如權限攔截等功能。

3> Strut2提供了類型轉換器,我們可以把特殊的請求參數轉換成需要的類型。在Struts1中,如果我們要實現同樣的功能,就必須向Struts1的底層實現BeanUtil注冊類型轉換器才行。

4> Struts2提供支持多種表現層技術,如:JSPfreeMarkerVelocity

5> Struts2的輸入校驗可以對指定方法進行校驗,解決了Struts1長久之痛。

6> 提供了全局范圍、包范圍和Action范圍的國際化資源文件管理實現

 

搭建Struts2環境時,我們一般需要做以下幾個步驟的工作

1》找到開發Struts2應用需要使用到的jar文件.

2》編寫Struts2的配置文件

3》在web.xml中加入Struts2 MVC框架啟動配置

 <package name="itcast" namespace="/test" extends="struts-default">
<action name="helloworld" class="cn.itcast.action.HelloWorldAction" method="execute" >
<result name="success">/hello.jsp</result>
</action>
 </package> 

     在struts2框架中使用包來管理Action,包的作用和Java中的類包是非常類似的,它主要用於管理一組業務功能相關的action。在實際應用中,我們應該把一組業務功能相關的Action放在同一個包下。

    配置包時必須指定name屬性,該name屬性值可以任意取名,但必須唯一,他不對應java的類包,如果其他包要繼承該包,必須通過該屬性進行引用。包的namespace屬性用於定義該包的命名空間,命名空間作為訪問該包下的Action的路徑的一部分,如訪問上面例子的Action,訪問路徑為:/test/helloworld.action。 namespace屬性可以不配置,對本例而言,如果不指定該屬性,默認的命名空間為“”(空字符串)。

    通常每個包都應該繼承struts-default包, 因為Struts2很多核心的功能都是攔截器來實現。如:從請求中把請求參數封裝到action、文件上傳和數據驗證等等都是通過攔截器實現的。 struts-default定義了這些攔截器和Result類型。可以這么說:當包繼承了struts-default才能使用struts2提供的核心功能。 struts-default包是在struts2-core-2.x.x.jar文件中的struts-default.xml中定義。 struts-default.xml也是Struts2默認配置文件。 Struts2每次都會自動加載 struts-default.xml文件。

包還可以通過abstract=“true”定義為抽象包,抽象包中不能包含action

 

Action名稱的搜索順序

 

1.獲得請求路徑的URI,例如url是:http://server/struts2/path1/path2/path3/test.action

 

2.首先尋找namespace/path1/path2/path3package,如果存在這個package,則在這個package中尋找名字為testaction,如果不存在這個package則轉步驟3

 

3.尋找namespace/path1/path2package,如果存在這個package,則在這個package中尋找名字為testaction,如果不存在這個package,則轉步驟4

 

4.尋找namespace/path1package,如果存在這個package,則在這個package中尋找名字為testaction,如果仍然不存在這個package,就去默認的namaspacepackage下面去找名字為testaction(默認的命名空間為空字符串"" ),如果還是找不到,頁面提示找不到action

Action配置中的各項默認值:

 

<package name="itcast" namespace="/test" extends="struts-default">
        <action name="helloworld" class="cn.itcast.action.HelloWorldAction"  method="execute" >
<result name="success">/WEB-INF/page/hello.jsp</result>
        </action>
  </package> 

 

1>如果沒有為action指定class,默認是ActionSupport

2>如果沒有為action指定method,默認執行action中的execute() 方法。

3>如果沒有指定resultname屬性,默認值為success

用struts2完成登錄案例:

index.jsp中:

 

<body>
  <div align="center"> 
     <h1>用戶登錄界面</h1>
     <div>${msg}</div>
     <div>
      <form action="${pageContext.request.contextPath}/csdn/loginAction" method="post">
        <table>
           <tr>
             <td> 用戶名</td>
             <td><input type="text" name="username"/>
             </td>
           </tr>
           <tr>
            <td>密碼</td>
            <td>
              <input type="password" name="userpass"/>
            </td> 
           </tr>
           <tr>
             <td colspan="2">
              <input type="submit" value="登錄">
                  
              <input type="reset">
             </td>
           </tr>
        </table>
      </form>
      </div>
      </div>
  </body>
在LoginAction類中
public class LoginAction implements Action{
  private String username;
  private String userpass;
  private String msg;
注意:此處省略了get,set方法
public String login(){
System.out.println("你傳遞的參數值是:"+username+"----------"+userpass);
if("feng".equals(username)){
return SUCCESS;
}
this.setMsg("重新登錄");
return INPUT;
}
}
Struts2的配置文件中:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC 
"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" 
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
  <package name="redarmys" extends="struts-default" namespace="/csdn">
    <action name="loginAction" class="cn.csdn.action.LoginAction"  method="login">
       <result name="success">/sc.jsp</result>
       <result name="input">/index.jsp</result>
    </action>
  </package>
</struts>

 

注意:解決在斷網環境下,配置文件無提示的問題

    我們可以看到Struts.xml在斷網的情況下,前面有一個嘆號,這時,我們按alt+/ 沒有提示,這是因為” http://struts.apache.org/dtds/struts-2.0.dtd”是一個網絡地址,如果上網的話,IDE會自動幫我們下載此文件,如果斷網就沒有辦法了,但是我們還是有解決方法的.
   首先在源碼包里找到struts-2.0.dtd這個文件
在MyEclipse中菜單欄中選擇:windowPreferencesMyEclipseFiles and Editors
Xmlxml Catalog在右邊的下拉框中選擇User Specified Entries點擊Add按鈕左邊選中Catalog Entry右邊的location中點擊File System在彈出的對話框中將搜索到的文件全路徑    復制上去,並選中struts-2.0.dtd在key type下拉框中選擇URIkey文本框中填寫: http://struts.apache.org/dtds/struts-2.0.dtd ,點擊OK即可. 這時我們可以看到Struts.xml文件中還有嘆號,我們可以在Struts標簽與package標簽中打入一個回車后保存即可.

問題一:大家可以看到這里用到了EL表達式,我們知道EL表達式只能取出page,request,session,application四個范圍之一里面的數據,但是我這里並沒有將任何數據放入到四個范圍中,為什么這里能夠取出數據來呢?
問題二: Chapter1Action是一個非常普通的類,它不是Servlet,為什么能夠處理用戶的請求呢?

是因為:

Struts2用於處理用戶請求的Action,沒有與Servlet API耦合,顯示無法處理用戶請求,而Struts2提供了系列攔截器,該系列攔截器負責將HttpServletRequest請求中的請求參數解析出來,傳入到Action中,並調用Action的execute方法來處理用戶的請求.

Struts.xml配置中包與action的介紹:

<package name="chapter1" namespace="/chapter1" extends="struts-default">
<action name="HelloWorld" class="chapter1.action.Chapter1Action" method="execute">
   <result name="success">/WEB-INF/JspPage/chapter1/HelloWorld.jsp</result>
</action>
</package>

Struts2框架中使用包來管理action,避免了Servlet在web.xml中難以管理的與維護的局面.包的作用和java中的類包是非常類似的,它主要用於管理一組業務功能相關的action,在實際應用中,我們應該把一組業務功能相關的action 放在同一個包下.

配置包時必須指定name屬性,該name屬性值可以任意取名,但必須唯一,如果其他包要繼承該包,必須通過該屬性進行引用,包的namespace屬性用於定義該包的命名空間,命名空間作用為訪問該包下的action路徑的一部分,見示例.namespace屬性可以不配置,如果不指定該屬性,默認的命名空間為””

通常每個包都應該繼承struts-default包,因為struts2很多核心功能都是攔截來實現的,如,從請求中把請求參數封閉到action,文件上傳和數據驗證等都是通過攔截器實現的,struts-default定義了這些攔截器和Result類型,可以這么說,當包繼承了struts-default才能使用struts2提供的核心功能,struts-default包是在struts2-core-2.xx.jar文件中的struts-defalut.xml中定義,struts-default.xml也是struts2默認配置文件,struts2每次都會自動加載struts-default.xml文件.

package還有一個abstract=”true”屬性,指定此包為抽象包,和抽象類的概念差不多,說明此包只能被其他包繼承,則它里面不允許包含action元素.

<action name="HelloWorld" class="chapter1.action.Chapter1Action" method="execute">
<result name="success">/WEB-INF/JspPage/chapter1/HelloWorld.jsp</result>
</action> 


Action 元素method屬性,默認值為method=”execute”,也就是當action接收到請求后,交給哪個方法去處理,默認的是交給execute方法去處理,當然,也可以交給其他方法,后面會講解到.

<result name="success">/WEB-INF/JspPage/chapter1/HelloWorld.jsp</result> 


result元素主要定義視圖的跳轉和返回的行為及類型,后面會詳細介紹.

struts.xml文件的分離
從上一個項目實踐中可以看到,我們的web.xml文件非常之大,到后來是越來越難的查找與維護,看得頭都是大的,Struts2配置文件可以分離,很好的解決了此問題.
通過主次配置文件的分離,可以加強團隊間的合作,並且互不打擾彼此的配置文件,出了問題也知道責任在哪里.
在實例開發中也是這樣做的,通過一個主文件中,打開全局開關,引入其他子配置文件,如:

<?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.enable.DynamicMethodInvocation" value="false"/>
<constant name="struts.devMode" value="false"/>
<constant name="struts.i18n.encoding" value="UTF-8"/>
<constant name="struts.serve.static.browserCache " value="false"/>
<include file="chapter1.xml"/>
</struts> 

常用開關的介紹
<constant name="struts.i18n.encoding" value="UTF-8"/>
指定Web應用的默認編碼集,相當於調用HttpServletRequest的setCharacterEncoding方法
<constant name="struts.action.extension" value="do"/>
該屬性指定需要Struts 2處理的請求后綴,該屬性的默認值是action,即所有匹配*.action的請求都由Struts 2處理。    如果用戶需要指定多個請求后綴,則多個后綴之間以英文逗號(,)隔開。   
<constant name="struts.serve.static.browserCache " value="false"/>
設置瀏覽器是否緩存靜態內容,默認值為true,開發階段最好false
<constant name="struts.configuration.xml.reload" value="true"/>
當struts的配置文件修改后,系統是否自動重新加載該文件,默認值為false,開發階段最好true
<constant name="struts.devMode" value="true"/>
開發模式下設為true,這樣可以打印出更詳細的錯誤信息
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
動態方法調用,可以解決多個請求對應一個Servlet的問題,后面詳細講解,默認為true,關閉則設為false.

這里只是列舉了一些常用的開關,當然還有許多其他的開關,后面的學習中會逐漸介紹,大家在這里先了解一下.

以下是從網上摘得的,比較全的一個資料

 

struts.serve.static.browserCache 該屬性設置瀏覽器是否緩存靜態內容。當應用處於開發階段時,我們希望每次請求都獲得服務器的最新響應,則可設置該屬性為false。

struts.enable.DynamicMethodInvocation 該屬性設置Struts 2是否支持動態方法調用,該屬性的默認值是true。如果需要關閉動態方法調用,則可設置該屬性為false。

struts.enable.SlashesInActionNames 該屬性設置Struts 2是否允許在Action名中使用斜線,該屬性的默認值是false。如果開發者希望允許在Action名中使用斜線,則可設置該屬性為true。

struts.tag.altSyntax 該屬性指定是否允許在Struts 2標簽中使用表達式語法,因為通常都需要在標簽中使用表達式語法,故此屬性應該設置為true,該屬性的默認值是true。

struts.devMode該屬性設置Struts 2應用是否使用開發模式。如果設置該屬性為true,則可以在應用出錯時顯示更多、更友好的出錯提示。該屬性只接受true和flase兩個值,該屬性的默認值是false。通常,應用在開發階段,將該屬性設置為true,當進入產品發布階段后,則該屬性設置為false。

struts.i18n.reload該屬性設置是否每次HTTP請求到達時,系統都重新加載資源文件。該屬性默認值是false。在開發階段將該屬性設置為true會更有利於開發,但在產品發布階段應將該屬性設置為false。

提示 開發階段將該屬性設置了true,將可以在每次請求時都重新加載國際化資源文件,從而可以讓開發者看到實時開發效果;產品發布階段應該將該屬性設置為false,是為了提供響應性能,每次請求都需要重新加載資源文件會大大降低應用的性能。

struts.ui.theme該屬性指定視圖標簽默認的視圖主題,該屬性的默認值是xhtml。
struts.ui.templateDir該屬性指定視圖主題所需要模板文件的位置,該屬性的默認值是template,即默認加載template路徑下的模板文件。
struts.ui.templateSuffix該屬性指定模板文件的后綴,該屬性的默認屬性值是ftl。該屬性還允許使用ftl、vm或jsp,分別對應FreeMarker、Velocity和JSP模板。
struts.configuration.xml.reload該屬性設置當struts.xml文件改變后,系統是否自動重新加載該文件。該屬性的默認值是false。
struts.velocity.configfile該屬性指定Velocity框架所需的velocity.properties文件的位置。該屬性的默認值為velocity.properties。
struts.velocity.contexts該屬性指定Velocity框架的Context位置,如果該框架有多個Context,則多個Context之間以英文逗號(,)隔開。
struts.velocity.toolboxlocation該屬性指定Velocity框架的toolbox的位置。
struts.url.http.port該屬性指定Web應用所在的監聽端口。該屬性通常沒有太大的用戶,只是當Struts 2需要生成URL時(例如Url標簽),該屬性才提供Web應用的默認端口。
struts.url.https.port該屬性類似於struts.url.http.port屬性的作用,區別是該屬性指定的是Web應用的加密服務端口。
struts.url.includeParams該屬性指定Struts 2生成URL時是否包含請求參數。該屬性接受none、get和all三個屬性值,分別對應於不包含、僅包含GET類型請求參數和包含全部請求參數。
struts.custom.i18n.resources該屬性指定Struts 2應用所需要的國際化資源文件,如果有多份國際化資源文件,則多個資源文件的文件名以英文逗號(,)隔開。
struts.dispatcher.parametersWorkaround 對於某些Java EE服務器,不支持HttpServlet Request調用getParameterMap()方法,此時可以設置該屬性值為true來解決該問題。該屬性的默認值是false。對於WebLogic、Orion和OC4J服務器,通常應該設置該屬性為true。
struts.freemarker.manager.classname 該屬性指定Struts 2使用的FreeMarker管理器。該屬性的默認值是org.apache.struts2.views.freemarker.FreemarkerManager,這是Struts 2內建的FreeMarker管理器。
struts.freemarker.wrapper.altMap該屬性只支持true和false兩個屬性值,默認值是true。通常無需修改該屬性值。
struts.xslt.nocache 該屬性指定XSLT Result是否使用樣式表緩存。當應用處於開發階段時,該屬性通常被設置為true;當應用處於產品使用階段時,該屬性通常被設置為false。
struts.configuration.files 該屬性指定Struts 2框架默認加載的配置文件,如果需要指定默認加載多個配置文件,則多個配置文件的文件名之間以英文逗號(,)隔開。該屬性的默認值為struts-default.xml,struts-plugin.xml,struts.xml,看到該屬性值,讀者應該明白為什么Struts 2框架默認加載struts.xml文件了。 
在請求時,路徑后的后綴action可要可不要,即下面的兩種請求都是可以的
http://localhost:8080/Struts2/chapter1/HelloWorld
http://localhost:8080/Struts2/chapter1/HelloWorld.action

Action配置中的各項默認值
請看下面的代碼
<action name="Login">
<result>/WEB-INF/JspPage/chapter1/Login.jsp</result>
</action> 
我們發現,當我們請求的路徑為http://localhost:8080/Struts2/chapter1/Login時,同樣可以實現頁面的跳轉,這是怎么回事呢?
如果沒有為action指定class,默認是ActionSupport類
<action name="Login"> 
相當於 
<action name="Login" class="com.opensymphony.xwork2.ActionSupport">
如果沒有為action指定method,默認執行action中的execute()方法
<action name="Login">
相當於
<action name="Login" class="com.opensymphony.xwork2.ActionSupport"
method="execute">
如果沒有指定result的name屬性,默認值為success.
<result>相當於<result name="success">


提出一個問題ActionSupport這個類到底是個什么類呢?
首先要肯定的一點是他是一個具有execute方法的類,並且execute方法返回”success”字符串,因為只有這樣,前面的運行結果才能說的通. ActionSupport還實現了很多其他的結果,提供了許多定制的功能.


ActionSupport類的作用 
struts2不要求我們自己設計的action類繼承任何的struts基類或struts接口,但是我們為了方便實現我們自己的action,大多數情況下都會繼承com.opensymphony.xwork2.ActionSupport類,並重寫此類里的public String execute() throws Exception方法。因為此類中實現了很多的實用借口,提供了很多默認方法,這些默認方法包括國際化信息的方法、默認的處理用戶請求的方法等,這樣可以大大的簡化Acion的開發。 
Struts2中通常直接使用Action來封裝HTTP請求參數,因此,Action類里還應該包含與請求參數對應的屬性,並且為屬性提供對應的getter和setter方法。
課堂筆記
默認值
class="" ActionSupport
method="" execute
name="" “success”
Action接口里提供了一些常量及execute方法,通常我們自己寫的Action可以實現這個接口, ActionSupport已經實現了這個接口,並且還實現了驗證,國際化等功能的接口,所以我們自己寫的Action類通常會繼承ActionSupport這個類來達到啟用驗證框架,國際化,自動轉換等功能的目的.

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM