Struts2與Struts1.X

Apache Struts2原本就是舉世聞名的Webwork2,在各自經歷幾年的發展之後,Struts和WebWork社區決定合二爲一,也就是今天的Struts2。

  Struts是一個基於Model2的MVC框架,爲應用程序的WEB層提供了良好的結構嚴謹的實現。Struts發展較早,早期的Struts1.X已被很多J2EE程序員熟悉,經過多年來的發展,這支隊伍變得越來越大,很多企業級應用程序都是基於Struts開發的。

  Struts2與Struts1.X已經不能再放到一起比較,雖然都是對MVC架構模式的實現,本質卻完全不同。Struts2的前身是WebWork,其實現方式和功能都要優於Struts1.X,但是,Struts先入爲主,很多應用程序都基於Struts,其生命力和普及度使得WebWork落於下風。隨着新思想和新架構的不斷涌入,特別是WEB2.0被大量提及,Struts1.x顯然無法跟上日新月異的變化,在很多應用上顯得力不從心,最終催生了Struts2.0。可以說Struts2.0是爲變而變。

  很大程度上,Struts2.0無法避開投機取巧的嫌疑。不過,藉助Struts的名聲,加上WebWork構建良好的框架,二者取長補短,確實不失爲一種黃金組合和一種絕佳的宣傳方式。

  筆者杜撰此文時,可以下載到的最新版本爲2.1.0,但他的魅力已初露尖角,應該會有很好的前途。

  Struts2的新特徵

如果讀者熟悉Struts1.X,會發現Struts2比Struts1.X有了巨大的變化:

 

  Action 類:

  • Struts1要求Action類繼承一個抽象基類。Struts1的一個普遍問題是使用抽象類編程而不是接口。

  • Struts 2 Action類可以實現一個Action接口,也可實現其他接口,使可選和定製的服務成爲可能。Struts2提供一個ActionSupport基類去實現常用的接口。Action接口不是必須的,任何有execute標識的POJO對象都可以用作Struts2的Action對象。

  線程模式:

  • Struts1 Action是單例模式並且必須是線程安全的,因爲僅有Action的一個實例來處理所有的請求。單例策略限制了Struts1 Action能作的事,並且要在開發時特別小心。Action資源必須是線程安全的或同步的。

  • Struts2 Action對象爲每一個請求產生一個實例,因此沒有線程安全問題。(實際上,servlet容器給每個請求產生許多可丟棄的對象,並且不會導致性能和垃圾回收問題)

  Servlet 依賴: 

  • Struts1 Action 依賴於Servlet API ,因爲當一個Action被調用時HttpServletRequest 和 HttpServletResponse 被傳遞給execute方法。

  • Struts 2 Action不依賴於容器,允許Action脫離容器單獨被測試。如果需要,Struts2 Action仍然可以訪問初始的request和response。但是,其他的元素減少或者消除了直接訪問HttpServetRequest 和 HttpServletResponse的必要性。

  可測性:

  • 測試Struts1 Action的一個主要問題是execute方法暴露了servlet API(這使得測試要依賴於容器)。一個第三方擴展--Struts TestCase--提供了一套Struts1的模擬對象(來進行測試)。

  • Struts 2 Action可以通過初始化、設置屬性、調用方法來測試,“依賴注入”支持也使測試更容易。

  捕獲輸入:

  • Struts1 使用ActionForm對象捕獲輸入。所有的ActionForm必須繼承一個基類。因爲其他JavaBean不能用作ActionForm,開發者經常創建多餘的類捕獲輸入。動態Bean(DynaBeans)可以作爲創建傳統ActionForm的選擇,但是,開發者可能是在重新描述(創建)已經存在的JavaBean(仍然會導致有冗餘的javabean)。

  • Struts 2直接使用Action屬性作爲輸入屬性,消除了對第二個輸入對象的需求。輸入屬性可能是有自己(子)屬性的rich對象類型。Action屬性能夠通過web頁面上的taglibs訪問。Struts2也支持ActionForm模式。rich對象類型,包括業務對象,能夠用作輸入/輸出對象。這種ModelDriven 特性簡化了taglib對POJO輸入對象的引用。

  表達式語言:

  • Struts1 整合了JSTL,因此使用JSTL EL。這種EL有基本對象圖遍歷,但是對集合和索引屬性的支持很弱。

  • Struts2可以使用JSTL,但是也支持一個更強大和靈活的表達式語言--"Object Graph Notation Language" (OGNL).

  綁定值到頁面(view):

  • Struts 1使用標準JSP機制把對象綁定到頁面中來訪問。

  • Struts 2 使用 "ValueStack"技術,使taglib能夠訪問值而不需要把你的頁面(view)和對象綁定起來。ValueStack策略允許通過一系列名稱相同但類型不同的屬性重用頁面(view)。

  類型轉換:

  • Struts 1 ActionForm 屬性通常都是String類型。Struts1使用Commons-Beanutils進行類型轉換。每個類一個轉換器,對每一個實例來說是不可配置的。

  • Struts2 使用OGNL進行類型轉換。提供基本和常用對象的轉換器。

  校驗: 

  • Struts 1支持在ActionForm的validate方法中手動校驗,或者通過Commons Validator的擴展來校驗。同一個類可以有不同的校驗內容,但不能校驗子對象。

  • Struts2支持通過validate方法和XWork校驗框架來進行校驗。XWork校驗框架使用爲屬性類類型定義的校驗和內容校驗,來支持chain校驗子屬性

  Action執行的控制:

  • Struts1支持每一個模塊有單獨的Request Processors(生命週期),但是模塊中的所有Action必須共享相同的生命週期。

  • Struts2支持通過攔截器堆棧(Interceptor Stacks)爲每一個Action創建不同的生命週期。堆棧能夠根據需要和不同的Action一起使用。

  注:以上資料從網上搜集,來源:Struts開發組,翻譯:tianxinet(胖猴)。

  Struts2的環境要求

    Apache Struts2的環境需求如下:

 

  Servlet API 2.4

  JSP API 2.0

  Java 5

  需要提醒的是,在Struts中會用到Annotation,所以請將JDK版本升級到1.5.

  Struts2環境搭建

 

4.1Struts的下載

   從遊覽器輸入http://people.apache.org/builds/struts/,即可看到Struts的各個版本列表。從下圖中可以發現,現在Struts2.0的最新版是2.1.0,發佈於2007年10月29。      

  Struts2教程--第一章 搭建Struts2開發環境

 

  (圖1)

   Struts2教程--第一章 搭建Struts2開發環境

   (圖2)

  從圖2中可以看出,即可以分開下載,又可以一次全部下載。全部下載的大小爲83M,

   下表註明了各個壓縮包的作用。

  壓縮包名稱

  作用

  struts-2.1.0-docs.zip

  文檔,包含了Struts2API

  struts-2.1.0-lib.zip

  構建Struts2工程所需要的包

  struts-2.1.0-src.zip

  Struts2的所有源代碼

  struts2-blank-2.1.0.war

  空白工程

  struts-2.1.0-all.zip

  大集成,包括上面所有的內容

4.2 開發工具介紹

   目前J2EE開發工具主要分爲Eclipse和NetBeans兩大陣營,Eclipse的最高版本爲3.3,NetBeans的最高版本爲6.0.今天剛剛從新聞上看到,NetBeans6.0的英文正式版正式發佈了,真是可喜可賀。

   筆者在開發時以Eclipse爲主,但Eclipse並不支持WEB開發,需要安裝相應插件。MyEclipse是一個功能強大且框架支持非常廣泛的WEB開發插件,該產品是收費項目。目前MyEclipse的最高版本爲6.0,即便如此,尚不支持Struts2.0,我們只能手工配置Struts2.0的開發環境。

4.3 庫文件

   從網站上下載的Struts2包含了二三十個庫文件,但大多數是可選的,有些庫是插件,用於和其他框架的整合。

   讀者可自行下載struts2-blank-2.1.0.war壓縮包,展開後是一個非常簡單的項目,從WEB-INF/lib目錄中可以看到5個庫文件,解釋如下:

  包名

  說明

  commons-logging-1.0.4.jar

  日誌管理

  freemarker-2.3.8.jar

  表現層框架,定義了struts2的可視組件主題(theme)

  ognl-2.6.11.jar

  OGNL表達式語言,struts2支持該EL

  struts2-core-2.0.10.jar

  struts2的核心庫

  xwork-2.0.4.jar

  webwork的核心庫,自然需要它的支持

  Struts2教程--第一章 搭建Struts2開發環境 (圖3)

4.3 使用Eclipse搭建Struts2的開發環境4.3.1創建用戶庫

   將Struts2所需的包建成用戶庫,可以更加方便地進行管理和使用,這是一個好的習慣——編程從習慣開始。

   1.選擇菜單Window->Preferences->Java->Build Path->User Libraries。如圖4:

   Struts2教程--第一章 搭建Struts2開發環境

   (圖4)

   2.點擊右側的New…按鈕,創建一個新的用戶庫,彈出如圖5所示對話框:

   Struts2教程--第一章 搭建Struts2開發環境

   (圖5)

    3.輸入用戶庫的名稱,如:Struts2,點擊OK按鈕,該對話框自動關閉。結果如圖6所示:

 

   Struts2教程--第一章 搭建Struts2開發環境

   (圖6)

   此時,右側的按鈕被點亮。

   4.點擊“Add JARS…”按鈕,添加用戶庫所需的庫文件,在Struts2中,至少要包含上文中提到的5個庫文件。添加後效果如圖7所示:

   Struts2教程--第一章 搭建Struts2開發環境

   (圖7)

   5.點擊“OK”完成。

4.3.2開發第一個Struts2應用程序——世界,你好

   開發WEB應用程序,本文使用了MyEclipse插件。該插件爲收費軟件,目前提供英文版和日文版,不同的版本可以運行在Windows、Linux等操作系統上。爲了方便用戶,MyEclipse有一個Full版,連同Eclipse一起安裝,對於初學者而言,可以減少很多麻煩和困擾。

   讀者可自行去http://www.myeclipseide.com/網站下載該軟件的共享版本。建議讀者下載MyEclipse5.5(這也是筆者使用的版本),這個版本相對比較穩定,MyEclipse6.0還處於測試之中。

   入門教程總是以HelloWorld作爲學習的第一步,自然筆者也不例外。本示例從遊覽器輸入網址,提交請求後在頁面中顯示“世界,你好”的信息。

   1.新建WEB工程,如圖8所示:

   Struts2教程--第一章 搭建Struts2開發環境

   (圖8)

   2.點擊“Next”,輸入工程名,如圖9所示:

   Struts2教程--第一章 搭建Struts2開發環境

   (圖9)

   3.點擊“Finish”完成。

   4.現在將Struts2的庫導入到工程中,右擊工程名稱彈出快捷菜單,選擇Build Path->Add Libraries…,如圖10所示。

   Struts2教程--第一章 搭建Struts2開發環境

   (圖10)

   5.從彈出的對話框中選擇“User Libraries”,如圖11所示。

   Struts2教程--第一章 搭建Struts2開發環境

   (圖11)

   6. 單擊下一步,我們看到,上文中創建的用戶庫出現在列表中,在“Struts2”前的複選框上打勾,點擊“Finish”完成。如圖12。

   Struts2教程--第一章 搭建Struts2開發環境

   (圖12)

   7.將Struts2所帶的過濾器org.apache.struts2.dispatcher.FilterDispatcher配置到工程的web.xml文件中,默認情況下,該過濾器攔截請求字符串中以.action結尾的請求,並將該請求委託給指定的Action進行處理。最直觀的表現就是調用Action的execute()方法。代碼如下:

  代碼清單1:web.xml

  <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>

  注:在Sturts1.X中,該行爲由Servlet完成。

  8.創建包com.lizanhong.action,並在該包中創建HelloWorldAction類,該類繼承自com.opensymphony.xwork2.ActionSupport。理論上,Action可以不繼承任何類或實現任何接口,以增強程序的可測試性,這也是和Struts1.X不同的地方。但是,繼承自ActionSupport可以減少更多的編碼工作。

   在ActionSupport中,定義了方法execute(),當用戶向該Action發送請求時,會自動調用。程序代碼如下:

  代碼清單2:HelloWorldAction.java

package com.lizanhong.action;

import com.opensymphony.xwork2.ActionSupport;

publicclass HelloWorldAction extends ActionSupport {

  @Override

  public String execute() throws Exception {

    System.out.println("Action執行了。");

    returnSUCCESS;

  }

}

  注:ActionSupport是Struts2提供的類,功能類似於Struts1.x中的Action類,該類封裝了幾個有用的功能,比如:

  getText():從資源文件中獲取國際化消息。

  addFieldError():驗證輸入未通過時添加錯誤消息,支持國際化。

  execute():該方法一般會被重寫,當客戶端向Action發送請求時,會調用此方法。

  總結起來,該類主要提供了錯誤消息的支持和國際化支持。

   在工程類路徑下創建struts.xml文件,這是Struts2的配置文件,類似於Struts1.x中的struts-config.xml,在struts.xml文件中可以配置Action、Bean、Interceptor等組件。

  代碼清單3:struts.xml

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

  <include file="struts-default.xml"></include>

  

  <package name="a" extends="struts-default">

    <action name="helloworld" class="com.lizanhong.action.HelloWorldAction">

      <result>/result.jsp</result>

    </action>

  </package>

</struts>

  注:WEB應用程序的類路徑是指WEB-INF/classes目錄,在Eclipse中,創建在src目錄下的文件最終發佈後會自動複製到WEB-INF/classes目錄下。

  代碼清單3中涉及到很多標籤,以下是簡單的解釋:

  標籤名稱

  說明

  include

  包含其他xml文件,在示例中,這意味着struts.xml可以訪問定義在struts-default.xml文件中的組件。

  該元素可以使得Struts2定義多個配置文件,“分而治之”。

  要注意的是,任何一個struts2配置文件都應該和struts.xml有相同的格式,包括doctype,並且可以放在類路徑下的任何地方。

  package

  爲Action或截攔器分組。

  name:名稱,必填項,名稱自定義,沒特別要求。方便別的package引用。

  extends:package能繼承其他的package,即通過該屬性實現,值爲另一個package的name。

  在示例中,extends =”struts-default”是從struts-default.xml中繼承的。

  action

  定義Action,name屬性爲訪問時用到的名稱,class屬性是Action的類名。

  result

  根據Action的返回值定義頁面導航。

  Action的預定義的返回值有:

  String SUCCESS = "success";

  String NONE  = "none";

  String ERROR  = "error";

  String INPUT  = "input";

  String LOGIN  = "login";

  比如,當Action返回SUCCESS時希望轉到ok.jsp頁面,則可以這樣寫:

  <result name=”success”>ok.jsp</result>

  其中,name的缺省爲success。

   9.result.jsp是一個非常簡單的jsp頁面,輸出“世界,你好”。

  代碼清單4:result.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head>

  <base href="<%=basePath%>">

  

  <title>My JSP 'result.jsp' starting page</title>

  

  <meta http-equiv="pragma" content="no-cache">

  <meta http-equiv="cache-control" content="no-cache">

  <meta http-equiv="expires" content="0">  

  <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

  <meta http-equiv="description" content="This is my page">

  <!--

  <link rel="stylesheet" type="text/css" href="styles.css">

  -->

</head>

 

<body>

  世界,你好. <br>

</body>

</html>

  9.發佈工程,在瀏覽器中輸入:http://localhost:8081/Struts2Demo/helloworld.action,在控制檯輸出“Action執行了。”

  10.在瀏覽器的結果

  struts.xml的定義文件

代碼清單5:struts-2.0.dtd

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