程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 基於Struts 2開發Web應用

基於Struts 2開發Web應用

編輯:關於JAVA

引言

作為 Java Web 應用的典型框架,Struts 一直受到 Java 開發者的青睐,Struts 2 作為 Struts 發展的又一個裡程碑,以 WebWork 為基礎,提供了更易於使用,功能更強的 MVC 框架。同時它可以幫助開發人員更快速、高效、方便地實現一個 Java Web 應用系統。

對於開發人員來講,不同的項目可能需要不同的開發和運行 Struts 2 的平台,Struts 2 需要以下環境:Servlet API 2.4, JSP API 2.0, Java 5。IBM WebSphere Application Server 6.1(以下簡稱 WAS 6.1) 符合 Sturts 2 對運行環境的所有要求。另外,IBM Rational Software Architect 7(以下簡稱 RSA)提供了設計、開發各種應用的工具,其中包括創建和開發 Web 應用。二者的組合將是開發 Struts 2 的理想平台。

基於 RSA 及 WAS 搭建 Struts 2 開發平台

首先我們使用 RSA 創建一個動態 Web 項目,我們假設 RSA 中已經創建了一個 WAS 6.1 的服務器:

圖 1. 在 RSA 中創建 WAS 6.1 運行環境

在創建該項目的過程中,需要注意正確設置“目標運行時服務器”以及“動態 Web 模塊 版本“, 如下圖:

圖 2. 設置動態 Web 項目

其他按默認配置,點擊”完成”。創建完項目後,項目的基本包結構會自動生成,為了使該 Web 項目使用 Struts 2 框架,我們需要做一下配置:

配置 Struts 2 類庫

本示例使用 Struts 2.1.6 版本 , 所使用的類庫可以從 http://apache.etoak.com/struts/library/struts-2.1.6-lib.zip下載,如下圖,拷貝相應 jar 包到 Sample/WebContent/WEB-INF/lib 下。注意,本示例只拷貝了一些基本 jar 包,對於需要使用到 Struts 2 復雜功能的應用,需要另外拷貝相應 jar 包。

圖 3. 設置 Struts 2 依賴的 Jar 包

配置 web.xml

為了讓所有 web 請求通過 struts 2 框架處理,我們需要在 web.xml 中設置相應的 filter 以及 filter mapping, 對於 struts 2.1.6, 應設置成如下圖高亮部分:

圖 4. 在 web.xml 中設置 filter 和 filter mapping

對於 Struts 2 早期版本(2.1.3 之前),一般設置 filter 為 FilterDispatcher,具體如下:

<filter>
   <filter-name>struts2</filter-name>
   <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
   <filter-name>struts2</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

Stuts 2 的 taglib 已經自動包含在 struts-core.jar, 服務器會自動找到相應 taglib,所以 web.xml 中不再需要設置 taglib。

配置 Web 容器

當在 WAS 6.1 上運行 struts 2 應用程序時,需要另外設置 web 容器的一個定制屬性:

com.ibm.ws.webcontainer.invokefilterscompatibility=true, 否則,所有 Struts 2 Action 不起作用。該設置可以在 WAS 控制台上設置如下:

圖 5. 設置 Web 容器

以上步驟完成了開發 struts 2 應用的准備工作,下面我們開發一個示例。

示例開發

該示例包括兩個頁面,第一個是管理員浏覽所有系統用戶(userList.jsp),第二個是管理員創建一個新用戶(user.jsp)。圖 6 和圖 7 分別是兩個示例的應用截圖。

圖 6 . 浏覽系統用戶

圖 7. 點擊 “創建”按鈕創建新用戶

點擊“提交”,如果通過校驗,則返回到第一個頁面,如果校驗失敗,仍回到當前頁面,並提示錯誤信息。

下面我們開發該應用的各個組件:

創建 Action

創建基類

通過基類實現 SessionAware, ServletRequestAware, ServletResponseAware 接口,可以使用 IOC 方式初始化 session, request 和 response。這種實現可以方便所有子類訪問 session, request 和 response。

import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionSupport;

public class BaseAction extends ActionSupport
  implements SessionAware, ServletRequestAware, ServletResponseAware{

  private Map sessionMap;
  private HttpServletRequest request;
   private HttpServletResponse response;

   public void setServletRequest(HttpServletRequest request) {
     this.request = request;
   }

   public void setServletResponse(HttpServletResponse response) {
     this.response = response;
   }

   public void setSession(Map map){
    this.sessionMap=map;
   }

   public HttpServletRequest getHttpServletRequest(){
    return request;
   }

   public HttpServletResponse getHttpServletResponse(){
    return response;
   }

   public Map getSession(){
    return sessionMap;
   }
}

創建 , 配置 Action

在該示例中,所有 form 表單提交使用一個 Action 類,該類的不同方法將作為不同表單提交的 Action。在該示例中,execute(), createOrEditUser(), submitUser(), deleteUser() 對應於不同表單對應的 action。

圖 8. UserAction 代碼

在 Struts 2 應用中,action 的配置文件應該位於類根路徑下,一個 Struts 2 應用中可以存在多個 action 配置文件,但這些文件需要在 struts.xml 中引用,本例所有 action 在 struts-user.xml 中定義,struts.xml 引用 struts-user.xml。

在 struts-user.xml 中可以看到不同的類方法被配置成不同的 Action, 如果沒有指定方法,那麼 struts 2 框架會默認調用 execute(), 例如:”showUserList”

<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
   <package name="user" extends="struts-default" namespace="/admin">
     ……………
     <!-- user list -->
  <action name="showUserList" class="sample.action.UserAction">
   <result>/WEB-INF/page/userList.jsp</result>
  </action>

  <!-- add user -->
  <action name="createOrEditUser"
    class="sample.action.UserAction"
   method="createOrEditUser">
   <result>/WEB-INF/page/user.jsp</result>
  </action>

  <action name="submitUser"
    class="sample.action.UserAction"
   method="submitUser">
   <result name="input">/WEB-INF/page/user.jsp</result>
   <result name="userList" type="chain">showUserList</result>
  </action>
  ……………
  </package>
</struts>

在 Struts 2 中,如果一個 Action 需要調用另一個 Action, 可以設置 result 的 type 為 chain, 如前面代碼片段中的 <result name="userList"type="chain">showUserList</result>

開發頁面

在開發 Struts 2 應用時,不可避免會使用大量的 Struts 2 標簽,默認 Struts 2 解釋這些標簽生成 HTML 代碼時會加上一些額外的代碼,例如可能把 <tr><td> 自動加上,如果我們選擇自己靈活控制代碼格式,可以參考本示例在 struts.properties 裡設置 struts.ui.theme=simple, struts.properties 同樣位於類根路徑下:

圖 9.Struts 標簽及配置文件

下面我們通過 user.jsp 來展示 Struts 2 框架是如何關聯 Jsp, Action 以及表單字段的

<%@ taglib prefix="s2" uri="/struts-tags"%>
........
<s2:form action="submitUser" name="submitUser" namespace="/admin">

     <table>
       <tr>
         <td><s2:text name="User.Name"/></td>
         <td><s2:textfield name="user.userName"/></td>
       </tr>
       <tr>
         <td><s2:text name="User.Password"/></td>
         <td><s2:password name="user.password"/></td>
       </tr>
       <tr>
         <td><s2:text name="User.Email"/></td>
         <td><s2:textfield name="user.email"/></td>
       </tr>
       ……………
     </table>
</s2:form>

S2:form 標簽的 action 屬性指定了 form 要提交到的 action, 該 action 名已經在 struts-user.xml 中定義。Namespace 屬性和 struts-user.xml 中保持了一致,根據 struts-user.xml 的配置信息,該 form 就會被提交到 UserAction 的 submitUser 方法,但是表單各個字段值是如何被 Action 識別的呢?這是由代表 HTML 各種控件的 Struts 2 標簽 name 屬性指定的,例如 <s2:textfield name="user.userName"/> 就將該字段的值直接映射到 UserAction 的 user 實例變量的 userName 屬性,注意,這裡要求 user 對象對應的 User 類必須有一個空的構造函數,另外這裡的 user 應該是一個標准的 JavaBean, 所有屬性應該有 get,set 方法。

我們看一下表單提交後,action 是如何處理的:

public String submitUser() {
   userService.addUser(user);
   return "userList";
}

在調用該方法前,Struts 2 框架已經將所有表單參數自動組裝到 user 對象中,所以該方法可以直接訪問 user 對象,並對其做相應處理 , 該示例中的 userService 是負責 user 對象的增,刪,改操作。

添加完 user 對象,該 action 返回了一個字符串”userList”, 該字符串是 struts-user.xml 中 submitUser action 設置的一個返回結果,該返回結果其實是調用另一個 action 來顯示現有 user 列表。

表單校驗

Struts 2 提供了很多種校驗方式,一種是配置方式,可以用來校驗基本數據信息,另一種是編程校驗,可以用來校驗較為復雜的業務邏輯。

如果是通過配置來校驗,需要在 Action 類的同目錄下建一個 xml 文件,命名規則是 action 類名 -action 別名 -validation.xml。例如,本示例中:UserAction-submitUser-validation.xml, 當 submitUser action 被調用的時候,會先通過該 xml 配置進行校驗。下面代碼片段是本示例中配置的校驗參數,它指定了對哪些表單字段做哪些校驗:

<validators>
  <field name="user.userName">
  <field-validator type="requiredstring">
   <param name="trim">true</param>
   <message key="User.UserName.Required"/>
  </field-validator>
  <field-validator type="stringlength">
    <param name="minLength">1</param>
    <param name="maxLength">20</param>
    <message key="User.UserName.Length"></message>
   </field-validator>
  </field>

  <field name="user.email">
   <field-validator type="requiredstring">
     <message key="User.Email.Required"></message>
   </field-validator>
   <field-validator type="email">
     <message key="User.Email.Format"></message>
   </field-validator>
  </field>

</validators>

Struts 2 定義了一些默認類型,例如 ,email, 可以校驗 email 格式,在上例中 user.email 指定了校驗表單的 email 字段,type=”requiredstring”表明該字段是必須的,type=”email”表明要檢驗 email 格式。所有的錯誤信息可以通過 key 來國際化。

另一種是通過編程校驗,在 UserAction 中有一個方法:

public void validateSubmitUser(){
   if (user.getPassword().length() < 6){
     this.addFieldError("user.password", getText("User.Password.Length"));
   }

}

注意該方法的命名,validate+Action 方法名,也就是說該方法會在調用 submitUser Action 時自動被 Struts 2 框架調用。

國際化

Struts 2 中提供了各種機制對日期格式,數字格式做相應的國際化。例如通過 Action 同目錄下的 package.properties, 具體可以參照附件,示例代碼。

對於普通文本的國際化,需要做以下步驟:

設置國際化加載文件路徑

struts.properties 中的 struts.custom.i18n.resources 設置了 struts 2 需要自動加載的國際化文件

訪問國際化資源

任何繼承自 ActionSupport 的 Action 類都可以直接使用 getText 方法根據當前 locale 獲取相應鍵的值

在 JSP 中可以使用 OGNL 表達式 %{getText('key')} 或者 <s2:text name="key"/> 來訪問國際化資源。

最後,如果以上方式都不適用,可以使用 com.opensymphony.xwork2.util.LocalizedTextUtil 工具類來訪問國際化資源。

3.5 異常處理

一般來說,web 應用都會設置一些統一錯誤頁面,用來顯示那些未被 try catch 捕捉到的異常信息,該示例在 struts-user.xml 中加入了這樣的配置信息:

<global-results>
   <result name="Exception">/WEB-INF/page/error.jsp</result>
</global-results>

<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="Exception"/>
</global-exception-mappings>

該配置表示在當前 package 下的所有 action, 一旦有 java.lang.Exception 拋出,並且沒有被相應 action 捕獲的話,系統將顯示錯誤頁面,error.jsp

另外,struts 2 也支持在某個 action 內部定義異常處理,例如:

<action name=”xxx” class=”xxx” method=”xxx”>
   …….
   <exception-mapping exception="java.lang.Exception" result="custom_error"/>
   <result name="custom_error">/WEB-INF/page/common/error.jsp</result>
   …….
</action>

在錯誤頁面中可以通過 <s2:property value="%{exception.message}" /> 顯示異常信息。

總結

通過該示例開發,我們對 Struts 2 開發平台以及 Struts 2 框架有了一個基本認識,不過要熟練應用 Struts 2,還需要了解它的各類標簽,OGNL 表達式。另外 Struts 2 還提供了一些高級特性,如 Interceptor 機制,IOC 機制。充分利用這些新特性會幫助我們更快,更方便地實現一些 Web 應用。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved