Struts基本知識

應用程序文件

Struts 1.1 將許多公用類從 struts.jar 中分離出來。大多數公用功能(如 digestor 實用程序和 Bean 實用程序)已移至公用包中。需要將 commons jar 隨 Struts 實現類一起引用。Struts 實現類中已廣泛使用 commons 類。

如果不想遭遇那些惱人的 NoClassDefFound 錯誤,就需要確保 Struts Web 應用程序始終包含下列包。

包名稱
用途

commons-beanutils.jar

簡單易用的 Java 反射和內省 API 包裝器

commons-collections.jar

一組用於擴展和增強 Java Collections Framework 的類

commons-digester.jar

通常用於分析 XML 配置文件的 XML 到 Java 對象映射實用程序

commons-lang.jar

一組公用實用程序類,可以爲 java.lang 中的類提供附加功能

commons-logging.jar

各種日誌 API 實現的包裝器

commons-validator.jar

用於定義 XML 文件中的驗證類(驗證方法)和驗證規則的可擴展框架

jakarta-oro.jar

一組文本處理 Java 類,可以提供兼容 Perl 5 的正則表達式


備註:如果從 Struts 1.0 升級到 Struts 1.1,digestor 類將以單獨包的形式位於公用項目下。在 Struts 1.0 中,digestor 類是 Struts 源代碼的一部分。

對於任何 Struts 應用程序,類路徑中必須有上述類。

理解 Struts 配置文件
通過一個基於 XML 的配置文件來記錄和控制 Struts 配置。缺省情況下,該文件的名稱是 struts-config.xml,位於 Web 應用程序的 WEB-INF 目錄中。Struts 有一箇中央控制器 Servlet (org.apache.struts.action.ActionServlet),首次加載 Struts 應用程序時,它會對該配置文件進行分析。 

該配置文件包含 Action 類與 Form 類的映射。映射爲應用程序提供頁面流。因此,配置文件的兩個重要部分是 <form-beans><action-mappings>

  • 下面是一個示例 form-bean

<form-beans>

<form-bean
name="LoginForm"

type="com.test.LoginForm"/>


</form-beans>

對應的 action-mapping 是這樣的:

<action-mappings>

<action
path="/login"
type="com.test.LoginAction"
name="LoginForm"
scope="request"
validate="true"
input="/pages/Login.jsp"/>


</action-mappings>

如果 Struts 配置文件中提供的配置詳細信息正確,Struts 控制器會對該應用程序流實施控制。如果提供的路徑不正確或未在類加載器中找到 Form Bean 或 Action Bean,控制器將返回運行時錯誤。

 

Struts Form Bean

那麼,準確地講什麼是 Form Bean 呢?Form Bean 是一種 Java Bean,廣泛用於映射 HTML 表單與相應的 Java Bean。Form Bean 的編碼和使用都很簡單。在使用 Form Bean 時,需要密切注意以下幾點:

  1. Form Bean 映射到的是 HTML 表單上的元素或控件。例如,如果 HTML 表單包含名爲 name 的字段,Form Bean 就會包含名爲 name 的屬性。

  2. 在映射到 HTML 控件的 Form Bean 中定義的每個屬性都必須有與之對應的賦值方法和取值方法。例如,該屬性有兩個方法:setName()getName()。 

  3. Form Bean 還包含一個名爲 validate() 的方法。可以使用 validate 方法驗證表單項,如果驗證失敗,則填充 actionErrors 對象,並將控制權返還給調用頁面,隨後調用頁面會顯示這些錯誤。下一小節將對驗證和錯誤處理做更多介紹。

 

Action

Action 類主要用於處理來自視圖的數據和對該數據執行任何業務操作。Action 類是 org.apache.struts.action.Action(其實就是一個 HttpServlet)的擴展。因此實際上是在執行 Servlet。 

這些 action 類與 Servlet 不同,它們不是在 web.xml 中註冊,而是映射到 Struts 配置文件中的 action 表單。其類似於以下代碼:

<action
path="/login"
type="com.test.LoginAction"
name="LoginForm"
scope="request"
validate="true"
input="/pages/Login.jsp"/>

 

可以使用其中的 path 屬性 "/login" 調用 Servlet。

Action 類定義需要先行覆蓋,才能執行任何任務的 execute 方法。Execute 方法有權訪問對應視圖的 actionForm Bean、對整個 Struts 配置的引用、HttpServletRequest 對象及 HttpServletResponse 對象。這使 execute 方法能夠對 HttpSession 對象、HttpSelvletRequest 對象及 HttpServletResponse 對象執行操作。

 

public ActionForward execute(ActionMapping mapping,
                                                        ActionForm form, 
                                                       HttpServletRequest request, 
                                                       HttpServletResponse response)

 

備註:在 Struts 1.0 中,該方法的名稱是 perform()。Struts 1.1 已不支持該方法。

Action 類返回 ActionForward 對象。此 ActionForward 對象確定需要將請求發送到的正確視圖。還會在 Struts 配置文件中註冊需要將控制權轉交給的正確視圖。

在上例中,假定在登錄失敗時需要將控制權傳遞給 error.jsp,在登錄成功時需要將控制權傳遞給 nextPage.jsp。Forward 標記的註冊方式如下:

 

<action
path="/login"
type="com.test.LoginAction"
name="LoginForm"
scope="request"
validate="true"
input="/pages/Login.jsp">
<forward 
    name="failure" 
    path="/error.jsp"/>
<forward 
    name="success" 
    path="/nextPage.jsp"/>
</action>

 


Execute 方法通常以下列語句作爲結束語句。

return (mapping.findForward("failure"));

其中的 mapping 指的是 ActionMapping 對象。已定義了特定 action 的 "failure" 路徑。因此以上語句實際執行的操作是將請求發送給 error.jsp。 

以上示例中的 <forward> 標記具有局部作用域,可以在定義時所針對的 action 內使用。但也可以定義全局 forward。全局 forward 也在 Struts 配置文件中定義,這與任何其它配置信息是一樣的。正如定義全局變量那樣,全局 forward 可以在應用程序中的任何地方使用。


 

<global-forwards>
<forward
name="welcome"
path="/Welcome.jsp"/>
</global-forwards>

 

因此,可以在應用程序中的任何地方使用 mapping.findForward("welcome"),而它始終會將控制權轉交給 Welcome.jsp

 

Validate 方法和錯誤處理
如前所述,可以在 struts-config.xml 中禁用操作和驗證。Action 中央控制器將確保不進行驗證。

 

<action
path="/login"
type="com.test.LoginAction"
name="LoginForm"
scope="request"
validate="true"
input="/pages/Login.jsp"/>

 


Validate 方法返回 ActionErrors 對象。這些對象充當錯誤信息的容器。如果驗證失敗,將把這些對象返還給調用 JSP,它可以處理對象以顯示它們。


排除消息資源故障
消息資源幫助開發人員在一個集中位置存儲標籤、錯誤信息等內容,簡化了後續階段的維護工作。該集中位置是一個屬性文件,存儲在應用程序的類路徑中,因此組件可以方便地訪問。

以下是爲 Struts 應用程序定義消息資源的兩種方法:

  • web.xml 
  • struts-config.xml

對於 web.xml,將屬性文件定義爲 ActionServlet 的 param-value。下面是一個簡短的示例:

<servlet>
<servlet-name>action</servlet -name>
<servlet-class>
    org.apache.struts.action .ActionServlet
</servlet-class>
<init-param>
<param-name>
    application
</param-name>
<param-value>
   beatest.ApplicationResources
</param-value>
</init-param>
</servlet>

請注意,param-name 應用程序和值表示爲beatest.ApplicationResources這表示在應用程序類路徑的包 beatest 內一定存在一個名爲 ApplicationResources.properties 的屬性文件。

在 Struts 1.1 中,可以在 struts-config.xml 中定義資源包。

<message-resources parameter="beatest.ApplicationResources"/>

此處的參數爲必需值,它引用類路徑 beatest 包中的 ApplicationResources.properties 文件。使用 Struts 1.1 時可以有多個資源包,這使開發人員還能夠對資源包進行組織。例如,可以有這樣的包:

<message-resources key=”errorBundle”  parameter="beatest.ApplicationErrors"/>

<message-resources key=”labelsBundle”  parameter="beatest.ApplicationLabels"/>

可以在應用程序中對它們進行適當設置。如果用戶想要爲 HTML 顯示標籤,則可以使用 labelsBundle

<bean:message bundle="lablesBundle" key="some.message.key"/>

而如果想要顯示錯誤信息,則可以使用 errorBundle。

<bean:message bundle="errorBundle" key="some.error.message"/>

 

使用消息資源時的常見問題
開發 Struts 應用程序過程中的一個常見錯誤是:

 javax.servlet.jsp.JspException:Missing message for key "<some key name>"

要解決此問題,可以確認是否存在下列情況:

  • 消息不是從正確的資源包取得的。請確保引用的是真正包含所提及的鍵的正確的資源包。 

  • 資源屬性文件不在正確的位置或不在應用程序的類路徑中。應用程序資源屬性文件應位於 WEB-INF/classes 目錄中,或應爲 WEB-INF/lib 目錄中某個 .jar 文件的一部分。 

  •  使用 null="false" 可避免上述錯誤。例如:

     <bean:message bundle="lablesBundle" key="some.message.key" null="false">

    這樣將會設置一個消息資源包,在文件 MyWebAppResources.properties 的缺省鍵下提供該資源包。缺少的資源鍵將顯示爲“???keyname???”。 

 

排除 Struts 國際化故障
缺省情況下,Struts 在每個用戶的會話中提供一個 Locale 對象。可以根據用戶提供的信息對此 Locale 對象做適當設置。 

以下是 Struts 國際化檢查清單:

  1. 設置了 Locale Servlet 參數。
    確保將 ActionServlet 的 Locale 參數設置爲 true。缺省情況下將此參數設置爲 true,即缺省情況下啓用本地化。

  2. 使用了正確的應用程序資源 Servlet 參數。
    對於 MessageResource,如果指定了正確的語言環境,則 ActionServlet 將在類路徑中尋找該語言環境專用的屬性文件。例如,如果像下面這樣指定 MessageResource: 

    <message-resources parameter="beatest.ApplicationResources"/>

    對語言環境敏感的應用程序將尋找名稱爲 ApplicationResources_xx_XX.properties 的文件,其中 xx_XX 爲特定的語言環境,如 es_USfr_CA

    該屬性文件只不過是一個簡單的包含一組鍵值對的文本文件。用戶需要確保文件的名稱正確並位於類路徑中。建議將該文件置於 Web 應用程序的 WEB-INF/classes 目錄中。 

  3. 如果用戶不在缺省語言環境中,則可以在 ActionServlet 中更改 Locale 對象。可以通過替換會話中的 Locale 對象進行更改。 

    Locale locale = new Locale("English","US");
    session.setAttribute(Action.LOCALE_KEY,locale); 

  4. 如果使用了 Struts 控制器,則可以在 struts-config.xml 中將語言環境指定爲控制器聲明的一部分。 

    <controller processorClass="org.apache.struts.action.RequestProcessor" debug="2" locale="fr_CA"/>

 

Struts 應用程序內的擴展日誌記錄 

  1. ActionServletweb.xml 中使用調試級別來確保獲得擴展的調試消息。有效的 debug 值是 0(不記錄)到 6(最嚴重)。 

  2. 將 detail 參數設置爲調試來自 digestor 的消息。以下是 web.xml 的一個片斷。

    <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
    <param-name>config</param-name>
    <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <init-param>
    <param-name>debug</param-name>
    <param-value>4</param-value>
    </init-param>
    <init-param>
    <param-name>detail</param-name>
    <param-value>2</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
    </servlet>
    請注意其中的 debug 和 detail 級別。 

     

  3. 如果使用缺省的 RequestProcesor 控制器,請對附加調試消息使用控制器的 debug 參數。以下是 struts-config.xml 的一個片斷。
    <controller processorClass="org.apache.struts.action.RequestProcessor" debug="2"/>

Struts 應用程序性能問題

  • 爲對象使用適當的作用域
    避免使 HttpSession 膨脹,而應評估在請求中存儲對象這一方案的可行性。可以將不需要長時間持久存儲的對象作爲 HttpSessionRequest 的一部分來存儲,這些對象用後即會被銷燬。作爲一項慣例,應將 JSP 中 useBean 標記的作用域最小化。因此,Action 表單的子類不應具有會話或應用程序的作用域,除非已無其它方案可供選擇。 

  • gif 和 jpeg 數量過多
    站在用戶的角度看,其瀏覽器中頁面顯示的響應時間取決於下載速度和頁面的複雜性。例如,圖形的數量。即使各單項 Web 內容的下載都相當快,設計不佳的圖形極多的動態網站也會讓人有“慢”的感覺。 

  • 預編譯 JSP
    預編譯 JSP 可以爲首次訪問 Struts 應用程序的用戶提供更好的性能。請使用 weblogic.appc(WLS 8.1 及更高版本)或 weblogic.jspc 來預編譯應用程序。 

  • 刷新靜態頁面
    如果只修改了靜態文件,則可以刷新它們而不用重新部署整個應用程序。請使用 weblogic.deployer 實用程序來完成此任務。請參考
    http://e-docs.bea.com/wls/docs81/webapp/deployment.html (English)

  • 標記庫過多
    實際上,Struts 框架本身就使用了大量標記庫。除非不得已,建議在任何情況下都要最充分地利用這些現成的庫,而不要創建新庫。自定義標記會產生性能開銷。請儘可能少用。

  • 使用 Servlet 過濾器
    這可能會成爲性能開銷。請確認它是否爲應用程序可接受的開銷。 

  • 充分調整 JVM
    請確保充分調整 JVM。有關如何調整 JVM 的更多詳細信息,請參考 http://e-docs.bea.com/wls/docs81/perform/JVMTuning.html (English)。 

  • 將 EJB 與 Struts Web 應用程序打包在一起
    避免在 WebLogic Server 上將 EJB 檔案與 Web 應用程序作爲獨立的、彼此無關的應用程序進行部署。如果客戶端在同一企業應用程序內,WebLogic Server 會優化 EJB 訪問。

Struts 最佳實踐

  1. 始終依據 JSP 規範定義缺省錯誤頁面。這樣如果在處理 Struts 頁面過程中出錯,將顯示錯誤頁面而不是無任何內容的空白屏幕。在 WebLogic 中,可以通過引用 http://e-docs.bea.com/wls/docs81/webapp/web_xml.html#1017571 (English) 處的鏈接來設置錯誤頁面。

  2. 使用 ExceptionHandler 來處理異常。可以在 Struts-config 文件中聲明 ExceptionHandler。可以將控制權傳遞給相應的錯誤處理程序頁面。可以在需要將控制權傳遞給非標準錯誤頁面時使用它。 

  3. 將 EJB 與 Struts 一起使用時,使用 Facade 模型調用 EJB。避免直接調用實體。避免將句柄緩存到無狀態會話 Bean 中。

  4. 建議不使用 Struts 數據源,而應在進行任何數據庫相關操作時使用 WebLogic 數據源,以利用 WebLogic 提供的連接池和事務控制功能。

  5. 仍處於開發階段時,使用展開 war 格式部署應用程序以節省開發時間。應以開發模式啓動 WebLogic Server,以利用 WebLogic 提供的熱部署功能。

  6. 如果使用 EJB 和 Struts 應用程序間共享的實用程序類簡化對實用程序類和實用程序檔案的打包,則請使用 WebLogic 8.1 提供的 APP-INF 功能。

  7. 不將應用程序類添加到服務器的類路徑中。服務器處於運行狀態時,將無法更改服務器類路徑中的任何內容。

 

外部資源


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