Struts in Action

轉自:http://blog.csdn.net/Jiangcx/article/details/2234196

用了這麼長時間的Struts,卻從來沒有完整地看完一本書,經過一段時間Qone的開發,更是發現了對Struts掌握的不夠好,終於完整地把《Struts  in  Action》看了一遍,發現很多以前不會的東東,這本書不錯,從原理到實踐,都講的很好。希望以後能有時間再看幾遍。現將讀書筆記貼在這兒留作紀念。筆記寫的很簡單,只是撿一些自己不會的或認爲很重要的記了一下,看的是英文版,很多不知道怎麼翻譯的,也直接摘的英文原句。不推薦大家參考我的筆記,呵呵。


Struts In Action

----Building web applications with the leading Java framework

第一部分 初識Struts

第一章   簡介

1.1本書宗旨

本書旨在幫助web開發者更好地使用Struts web應用程序框架。Struts基於一些標準的技術,例如Java Beans,Java Servlets,JSP等。Struts能幫助web開發者快速簡單地構建web應用。

1.1.1誰創建了Struts

Struts是Apache Software Fundation的Jakarta項目的一部分。Struts的主要架構師和開發者是Craig R. McClanahan。

1.1.2 Struts爲何開源

         幾乎所有的Java工具和框架都是開源的,開源框架對大家來說是雙贏的。

1.1.3 爲什麼叫做Struts

         Struts名稱用以提醒我們結構的重要性。

1.2 什麼是應用程序框架

         框架是一個可複用的,半成品的應用,可以被特殊化以生產定製化的應用程序。

1.2.1 其他類型的框架

         Lucene,Scaffold Toolkit,Struts Validator,Tiles tag Library。

1.3 必需的技術

         這些技術也是所有Java web應用必需的技術。

1.3.1 HTTP

         Web應用使用HTTP來在瀏覽器端和服務器端之間傳輸數據。HTTP是一種無狀態的協議。HTTP能成爲通用標準的一個原因在於它的簡單性,HTTP請求和相應都是簡單的文本文檔。

         由於HTTP是無狀態的,這使跟蹤使用者和請求很成問題,通常的兩種方法是使用Cookies和URL重寫。Cookie是用戶電腦上的特殊的信息包。URL重寫在頁面地址中存儲一種特殊的引用用來跟蹤使用者。

1.3.2 CGI(Common Gateway Interface)

         第一種被廣泛使用的用來創造動態內容的標準是CGI。CGI使用標準的操作系統特性,例如環境變量或者標準I/O在web服務器和主機的其他應用程序之間創建一個橋或網關,其他應用程序可以查看web服務器發送給它的請求並創建定製化的響應。

         CGI的兩個缺點:爲每個請求創建CGI程序,操作系統不可移植。

1.3.3 Java Servlets

         Java Servlet平臺關注了CGI的兩個缺點,一是更好的性能和資源利用率,二是Java的操作系統可移植性。

         爲使通用的Web服務器可以訪問servlets,servlets被插放在容器中。

         與CGI程序不同,並不對每個request創建一個新的servlet,只是爲每一個請求創建一個線程,Java 線程比CGI程序使用的服務器端進程要節省資源。

1.3.4 JavaServer Pages

         Java Servlets使頁面設計和業務邏輯處理混在一起,無法實現明確的分工。

         爲向頁面引入動態元素,開發者可以在HTML中插入JSP腳本元素,共有三種:expressions(<%=%>),Scriplet(<%%>)和declarations(<%!%>)。

         一個JSP頁面實際就是一個Java Servlet。

1.3.5 JSP標籤

         Scritplet快速、簡單、強大,但是把java代碼和HTML混合在一起,一個更好的選擇是使用JSP標籤。

         大部分的Struts開發者使用JSP和自定義的標籤來創造應用中的動態內容。

1.3.6 JavaBean

         頁面的動態數據可以使用一個JavaBean來傳遞,JSP標籤可以使用這個JavaBean的屬性來定製動態內容。

1.3.7 Model 2

         Servlet/JSP的0.92發佈版把在同一個應用中使用JSP和Servlet的體系結構描述爲Model 2。

         Struts框架基於Model 2,並提供了一個基礎的自定義標籤庫,使Struts更易使用。

1.4 高矚遠瞻Struts

         Struts使用Model 2體系結構,Struts的ActionServlet控制導航流。Struts的Action類用來訪問業務類,當ActionServlet從容器接受到一個request時,它使用URI來決定使用哪一個Action來處理這個request。Action可以驗證輸入和從業務層獲取來自數據庫或其他數據設備的信息。

         爲了獲取輸入數據,Action並不是從request中獲取所有的數據,而是ActionServlet將輸入都綁定到一個JavaBean,輸入beans都是Struts的ActionForm類的子類。ActionServlet通過request的路徑來決定使用哪個ActionForm。ActionForm都繼承自org.apache.struts.action.ActionForm。

    每一個HTTP的request,都要使用一個HTTP的response來回答。通常,Struts的Action不直接產生response,而是跳轉到另外的資源如JSP。Struts提供了ActionForward類,可以用來使用邏輯名稱來存儲到達一個頁面的路徑。Action向Servlet選擇和返回一個ActionForward, Servlet使用存儲在ActionForward對象中的路徑來調用頁面和完成response。

         Struts將這些詳細信息都綁定到一個ActionMapping對象中,每一個ActionMapping都與一個特定的路徑相關,當這個路徑被請求時,Servlet獲取ActionMapping對象,這個對象告訴 Servlet使用哪一個Action,ActionForm和ActionForward。

         所有這些詳細信息,Action,ActionForm,ActionMapping,ActionForward,都在struts-config.xml文件中聲明。ActionServlet在啓動時讀取此文件並創建一個配置對象的數據庫。在運行時Struts引用這些對象,而不是文件本身。

1.4.1 構建一個簡單應用

         這個應用用來註冊用戶名和密碼,通過這個實例可以接觸到使用struts來開發應用的方方面面。

1.4.2 開發前的準備

         所需的工具:

n  JDK

n  一個現代的Web容器(例如Tomcat)

n  一個簡單的文本編輯器

部署一個web應用最方便的辦法是使用WAR文件(Web Archive file),只要簡單的把WAR文件放在Tomcat的webapps目錄下。

1.4.3 開始開發

n  創建ActionForm

ActionForm對於HTML表單中的每一個字段都對應一個屬性。ActionServlet負責匹配request和ActionForm中的屬性的參數,如果匹配就調用ActionForm的setter方法,設置從request得到的值。

n  創建Action

Action繼承自org.apache.struts.Action。ActionServlet創建ActionForm並傳遞給Action。Action一般負責驗證輸入,獲取業務信息和決定向servlet返回哪個ActionForward。

n  創建Struts配置文件(struts-config.xml)

Struts框架使用配置文件作爲部署的描述子。這使我們可以創建和改變與路徑關聯的ActionMapping,而無需重新編譯Java類。

n  創建頁面

1.4.4 Looking Back

1.5 總結

第二章   探索Struts框架

2.1 Talking the talk

2.2 爲何需要Struts

2.2.1 退一步,進三步

         很多現代的開發環境,包括Swing,都使用MVC結構作爲框架的基礎。

2.2.2 進入Struts

         Struts的中心是一個MVC式的控制器。Struts控制器連接view和model之間的鴻溝。

2.2.3 Struts控制器組件

         Struts控制器是一組可編程的組件,這些組件使開發者可以精確定義他們的應用程序如何與用戶交互。這些組件將笨拙的實現細節隱藏在邏輯名稱後面,

n  超鏈接

對於開發者來說,超鏈接是應用程序中一些資源的路徑,這些可能是頁面,或者是自定義的Action。它可以包含一些特殊的參數。在Struts中,開發者可以將超鏈接定義爲一個ActionForward。這些對象具有一個邏輯名稱和一個path屬性,開發者設定path屬性,然後通過邏輯名稱來引用這個ActionForward。

n  HTML表單

Struts提供了ActionForm類來處理來自HTML表單的輸入,驗證這些輸入,以及重新顯示這些表單。

Struts配置通過一組描述子來引用ActionForm類:<form-beans>和<form-bean>元素。Struts配置列出了它使用的ActionForm beans,並且賦予這些ActionForm類一個邏輯名稱,以在程序中引用。

n  自定義Actions

HTML表單使用一個action參數告訴瀏覽器向何處傳送表單數據,Struts框架提供了Action類來接受表單數據。框架自動地創建,傳送合適的ActionForm給Action對象。Action可以直接從ActionForm得到它需要的數據。Action返回一個ActionForward對象給控制器。

n  ActionMappings

ActionMapping使得同一個Action對象可以被不同的映射使用,例如一個mapping使用需要驗證,另一個不需要驗證。

n  ActionServlet

Struts的ActionServlet一直在幕後工作,將所有其他的組件連接起來。

n  區域化

Struts組件具有區域化的特性。

2.2.4 使用Struts開發web應用程序

         Struts將表現層與Model分離。

2.3 爲何需要框架

         爲何web開發具有挑戰性?

2.3.1 The web—a never-ending kludge

         Web開發者受雙層折磨:一是使用web瀏覽器作爲客戶端,二是使用web協議進行通信。Web瀏覽器使用HTTP協議進行通信,展現使用HTML創建的頁面。Web瀏覽器發送HTTP請求,產生HTML作爲響應。這對於預先寫好的頁面是一個不錯的平臺,但我們大部分人都是寫動態的頁面。

         HTTP協議和web瀏覽器決定了web應用的書寫方式,這種方式有很多限制。

2.3.2 Servlet解決方案

         Servlet構建於HTTP之上,並提供了session上下文用以幫助跟蹤應用程序的用戶。

         Servlet規範描述了一個管理servlets的容器。

         對於數據庫訪問,Java編程框架提供了JDBC。

         對於訪問遠程數據庫的高性能應用,可以使用EJB平臺,大部分的Java應用程序框架,包括Struts,都可以在EJB上使用。

         Struts構建在servlet平臺之上,提供了無縫的環境。

2.3.3 Servlet框架

         通常來說,Web應用程序框架的焦點是輔助從web瀏覽器取得數據,給程序結構使用,和將程序結構的數據輸送到web瀏覽器,展示給用戶。

通用框架策略

Java web應用程序框架使用幾個通用的技術來使產品的設計、書寫、維護更加容易:

n  外部配置文件。提供開發者不想混入代碼的一些實現細節。

n  中心控制器

n  外部表現系統

2.3.4 白盒—黑盒體

         白盒框架很強地依賴於面向對象的特性如繼承和動態綁定,而黑盒框架傾向於爲可插入的組件定義接口,並且提供基於這些接口的基礎組件。

2.4 Struts,Model 2和MVC

2.4.1 MVC的演化

         MVC是構建Smalltalk程序的一個框架。

2.4.2 Model 2的興起

         將JSP與Servlet一起使用被稱作是Model 2(只使用JSP爲Model 1)。

2.4.3 應用程序分層—解耦View

         Model 2與MVC被認爲是不同的一個原因是觀察者通知模式在web環境下不能很好地工作。HTTP是一個pull的協議,客戶端請求,服務器端響應,沒有請求就沒有響應。觀察者模式需要一個push的協議。

         分層的web應用使用的是一個“平”的MVC模式。

2.4.4 Struts對Model 2,MVC和分層結構的實現

         Struts對Model 2的實現是,提供了一個控制器servlet用來管理jsp頁面和其他表現層設備之間的流轉。Struts對MVC和分層結構的實現是:使用ActionForwards和ActionMappings保持控制流決策處於表現層之外,

2.5 Struts控制流

2.5.1 The big picture

Struts的請求響應過程:

n  客戶請求匹配Action URI模式的路徑

n  容器將請求傳遞給ActionServlet

n  如果是模塊化的應用程序,ActionServlet選擇相應的模塊

n  ActionServlet查找路徑的映射

n  如果映射指定了一個form bean,ActionServlet檢查是否已經存在,否則創建一個

n  如果存在form bean,則ActionServlet重置form bean,並根據HTTP請求重新計算

n  如果映射的validate屬性設置爲true,則調用form bean的validate方法

n  如果驗證失敗,servlet將轉發到input屬性指定的路徑,本控制流結束

n  如果映射指定了一個Action類型,如果已經存在則重用,否則實例化一個對象

n  調用Action的perform或者execute方法,傳遞給它已經實例化的form bean,或者null。

n  Action可以創建form bean,調用業務對象,或者做其他一些該做的事情

n  Action向ActionServlet返回一個ActionForward對象

n  如果返回的ActionForward是另一個Action URI,則重新開始;否則顯示頁面或其他資源。通常是一個jsp頁面,使用Jasper或同等物來產生頁面。

n  如果Jsp使用了Struts的HTML標籤,則從request中取得合適的ActionForm,並從ActionForm產生控件。否則<html:form>產生一個ActionForm,從Struts1.1開始,form標籤如果自己創建ActionForm則調用ActionForm的reset方法。

2.5.2 細節

Request被容器接收

Struts框架的主幹組件是ActionServlet。同所有的servlet一樣,他存活在一個容器之中,如Tomcat,Resin或Weblogic。當容器啓動的時候,它讀取部署描述子(web.xml)來決定加載哪些servlets。

         其中一個標準的servlet設置是servlet mapping。容器使用這樣的設置來決定哪些請求發送給哪一個servlet。

<servlet-mapping>

<servlet-name>action</servlet-name>

<url-pattern>/do/*</url-pattern>

</servlet-mapping>

Request被我們的ActionServlet接收

         當我們的ActionServlet接收一個請求時,使用一連串的操作來處理地域化,映射,form bean,最後是Action。

處理MultiPartRequest。如果是Multipart請求(表單具有MIME附件),則servlet使用一個特殊的句柄(handler)來包裝這個request,以避免在後來的處理中出錯。

處理路徑。ActionServlet檢查路徑是否是一個應用程序模塊的路徑。如果是,則選擇相應模塊的配置。

處理地域化。缺省情況下,ActionServlet將檢查用戶的會話中是否存在一個標準的locale對象。如果不存在ActionServlet將放一個這樣的對象在session中。這個對象用來向每一個用戶提供區域化的表現。

處理內容和NoCache。缺省的MIME類型和可選的request頭被加到響應中。

處理映射。ActionServlet檢查是否存在一個mapping與我們正在處理的path相對應,如果沒有找到則轉發到缺省的Action,如果沒有缺省的Action則產生一個“bad request”錯誤。如果找到這樣的mapping,則放在request中以備後來使用。

處理角色。ActionServlet檢查用戶是否被授權訪問這個Action。

處理ActionForm。ActionServlet檢查mapping是否指定了一個ActionForm。如果指定了,則ActionServlet檢查在指定的範圍內(缺省是session範圍)是否存在一個對象,如果不存在,則創建一個對象。

處理算值。調用ActionForm的reset方法,並使用反射自動產生值。符合ActionForm屬性的參數將被應用。其他的參數或屬性被忽略。

處理驗證。調用ActionForm的validate方法,如果返回false,則控制交給mapping指定的input屬性,action不會被處理。

處理轉發或包含。如果ActionMapping指定了forward或include屬性,則控制轉交給另一個資源。否則ActionServlet將請求代理給Action對象。

處理Action。如果mapping指定了一個Action類型,則servlet檢查是否已經存在一個Action類型的實例化對象,如果沒有找到則實例化一個Action類型的對象,每一個類只有一個Action對象(單例模式),這個Action對象通過多線程處理所有的請求。Servlet調用Action的perform或execute方法,並把actionmapping,request,response和form bean傳遞給這個方法。

         Action是一個控制類,不應該用來處理應用程序的核心業務邏輯。

Action返回一個ActionForward

Jasper或同等物產生一個Jsp

         當Servlet發送一個請求給Jsp時,請求由其他的服務,如Jasper來處理。

其他的servlet產生響應

         處理完Action後,request可以傳遞給其他的servlet或服務。

2.5.3 Struts高效嗎?

         通常來講,Struts應當會提交適度設計的Web應用。

Struts不僅thread-safe而且thread-dependant。

ActionForm beans最小化子類代碼並縮短了子類繼承結構。

Struts標籤庫提供通用的功能。

Struts組件是可以被應用程序重用的。

Struts的區域化策略減少了重複JSP的需要。

Struts是使用開發的體系結構設計的。

Struts是輕量級的。

Struts是符合標準的。

Struts是開源的,且文檔比較充分。

Struts是獨立於model的。

2.6 Struts的長處與短處

2.6.1 弱點

第三章    構建一個簡單的應用程序

3.1 Strut By Strut

3.1.1 爲什麼選擇一個Logon程序?

         容易理解、簡單自包含、很多應用程序都需要。

3.2 總覽Logon程序

3.2.1 開始旅程

3.2.2 將要看到的頁面

         歡迎頁面和Logon頁面。

3.2.3 歡迎頁面

3.2.4 Logon頁面

3.2.5 再看歡迎頁面

3.2.6 與歡迎頁面說再見

3.2.7 聚集的特性

3.3 深入剖析Logon應用程序

3.3.1 歡迎頁面的瀏覽器代碼

Jsessionid鍵值:爲了跟蹤用戶,使用cookies和URL重寫技術。但是不是所有的瀏覽器客戶端都支持cookies,所以第一次請求時,容器都會創建一個jsessionid,如果在接下來的請求中容器發現客戶端接受cookies,則可以略過重寫URL。

3.3.2 歡迎頁面的JSP代碼

<%@ taglib uri="/tags/struts-html" prefix="html" %>

<%@ taglib uri="/tags/struts-logic" prefix="logic" %>

是JSP的同等物,用來引入擴展標籤供頁面的其餘部分使用。

         <html:base/>產生一個標準的HTML的base標籤,一些引用,如圖片,可以使用與最初Jsp頁面的相對位置。之所以使用這個標籤,是因爲對於動態的應用程序,我們訪問的地址並不是Jsp頁面的地址,可能是Action,java類等的地址。

         Struts的所有邏輯標籤都使用this和notThis的形式,不提供else標籤。

         可以給一個連接一個邏輯名稱,使用邏輯名稱來引用(<html:link>)。這種映射在配置文件中配置。這樣,如果要修改鏈接,只需要在配置文件中修改一次。

3.3.3 歡迎頁面的配置代碼

         配置文件的缺省名稱是struts-config.xml。

3.3.4 Logon頁面的瀏覽器代碼

         標籤庫的描述子TLD在web.xml文件中給出。

         <html:form>標籤的focus屬性,產生javascript代碼,使相應的控件獲得焦點。

         <html:text>標籤產生一個文本域的HTML輸入控件。

         <html:password>的redisplay屬性可以控制返回時是否設置值。

         <html:submit>產生標準的HTML的submit控件。

         <html:reset>產生標準的HTML的reset控件。

3.3.5 Logon頁面的配置代碼

         /LogonSubmit:ActionMapping

         app.LogonForm

         app.LogonAction

3.3.6 LogonSubmit代碼

         ActionMapping的input屬性:如果驗證失敗,返回input指定的地方。

3.3.7 LogonForm代碼

         基類ActionForm包含reset方法,如果mapping的scope設置爲request,則不必實現reset方法。

3.3.8 LogonAction代碼

         Action的execute方法比perform方法提供了更好的異常處理,其他都一樣。

         Debug級別在Web部署描述子web.xml中指定。

3.3.9 LogoffAction代碼

3.4 構造一個應用程序

3.4.1 定義需求

3.4.2 規劃應用程序

視圖

控制器

模型

3.4.3 規劃代碼樹

3.4.4 配置開發工具

         使用ant作爲構建工具。

3.4.5 配置build.xml文件

3.4.6 配置web.xml文件

         Java2 Servlet框架使用web.xml文件來配置應用程序。標明使用的servlets和其他一些設置。對於Struts應用,只需要配置一個servlet和一些標籤庫。

3.4.7 配置struts-config.xml文件

welcome Action

容器要求必需使用一個頁面作爲welcome頁面。通常的解決方式是使用一個index.jsp,來重定向到welcome Action。

3.4.8 測試部署的結果

Struts Blank應用程序可以用來測試環境,它包含了很多系統檢查。

3.4.9 構造自己的歡迎頁面

3.4.10 構造Logon頁面

3.4.11 構造Constants類

3.4.12 構造其他類

3.4.13 創建用戶目錄

3.4.14 配置ActionErrors

         作爲構建的過程,要把要把應用程序資源文檔拷貝到classes目錄下,以便ActionServlet能夠找到。

3.4.15 編譯和測試Logon頁面

3.4.16 修補歡迎頁面

3.4.17 Struts的ActionForward Action

         我們要儘可能鏈接到Struts的Action,而不是JSP。但是爲每一個JSP配置一個Action非常麻煩,可以使用ForwardAction,只要將parameter屬性配置爲JSP的地址即可。

第四章   配置Struts組件

4.1 三個XML文件和一個Properties文件

         Struts開發者必需維護一些配置文件。

n  web.xml。這個文件是Java Servlet規範需要的,servlet/JSP容器需要此文件加載和啓動程序。

n  struts-config.xml。

n  build.xml。ant工具需要的,不是必需的。

n  application.properties。提供消息資源。

4.1.1 其他一些文件

         如果使用其他一些可選的組件如Tiles框架、Struts Validator,還需要配置其他一些XML配置文件。如果您把程序化成多個模塊,則每個模塊可以使用自己的struts配置文件和消息資源文件。

4.2 Web應用程序部署描述子

4.2.1 web.xml文件

         Struts框架包含兩個組件需要由應用程序的部署描述子來配置:ActionServlet和標籤庫,其中標籤庫是可選的。

         <load-on-startup>設置爲2,允許先加載其他的servlets。這樣就支持從ActionServlet繼承的情況。

         <taglib-location>提供與標籤庫描述子的相對位置,標籤庫描述子TLD是標籤庫的實際類型(Java類)。

4.2.2 ActionServlet參數

         multipartClass,用來處理文件上傳的類。

         validating,是否使用DTD來驗證Struts配置文件。

4.3 Struts配置

         Struts配置文件與ActionServlet一起創建應用程序的控制層。

4.3.1 細節,還是細節

         Struts配置文件中的每一個組件都是一個Java對象。

4.3.2 變更管理

         存在一些Struts GUIs,可以維護Struts的XML配置文件。

4.3.3Protected Variation的原則

         Struts配置文件的很大一部分細節是關於表示層的。

4.4 Struts配置元素

         Struts使用Digester及配置文件的DTD來解析Struts配置文件。

         Struts配置元素:

n  data-sources,包含一組DataSource對象(JDBC2.0標準擴展)

n  data-source,指定一個DataSource對象,作爲servlet上下文屬性

n  set-property,指定一個附加的JavaBean的方法名和初識值

n  global-exceptions,描述一組Action對象可能拋出的異常

n  exceptions,爲exception類型註冊ExceptionHandler

n  form-beans,描述一組bean描述子

n  form-bean,描述一個FormBean的子類,以便供<action>引用

n  form-properties,描述一個可以用來配置DynaActionForm及其子類的實例的JavaBean屬性

n  global-forwards,描述一組ActionForward,可以被所有Action用來作爲返回值

n  forward

n  action-mappings

n  action

n  controller,描述ControllerConfig bean,它封裝一個應用程序模塊的運行時配置

n  message-resources,描述一個MessageResources對象

n  plug-in,指定一個通用的應用程序插件模塊的類,可以接受應用啓動和關閉事件

Scioworks Camino和Struts Console可以直接管理Struts配置文件。Adalon和ObjectAssembly可以可視化設計產品,並生成初始的Struts配置文件,Java類和JSP

4.4.1 global-exceptions

         Struts框架提供了一個缺省的ExceptionHandler(org.apache.struts.action.ExceptionHandler),它將異常存儲爲request-scope的屬性,爲你的exception信息創建一個ActionError對象,並把控制轉發到你選擇的JSP或其他URI。<html:errors>會自動打印帶有地域版本的異常信息。ExceptionHandler可以被繼承以添加新的行爲。每一個異常都可以指定它自己的handler類。

         爲註冊異常,需要提供Exception類型,消息資源key,以及response路徑,如:

<exception

type="org.apache.struts.webapp.example.ExpiredPasswordException"

key="expired.password"

path="/changePassword.jsp"/>

4.4.2 form-beans

         DynaActionForms在創建的時候,需要額外的屬性,我們需要一個地方來存放這些元素。

         ActionFormBean也可以包含property屬性來使用DynaActionForm。

 


         <form-bean name="logonForm" type="org.apache.struts.action.DynaActionForm">

<form-property name="username" type="java.lang.String"/>

<form-property name="password" type="java.lang.String"/>

</form-bean>

         使用DynaActionForm不需要使用ActionForm的子類。

4.4.3 global-forwards

         ActionForward將一個邏輯名稱和一個URI聯繫起來。其他組件只需要引用這個邏輯名稱。

         ActionForward的主要使用者是Action。

4.4.4 action-mappings

         ActionMappings描述應用程序可以執行什麼樣的操作和指令。

4.4.5 controller

         Struts允許多個應用程序模塊共享一個控制器servlet。每一個模塊有自己的Struts配置文件,可以獨立於其他模塊開發。controller允許每一個模塊指定一個獨立的ActionServlet的參數。

4.4.6 message-resources

4.4.7 plug-in

         PlugIn接口聲明Init和Destroy方法,控制器可以在適當的時候調用。PlugIn Action可以在Struts配置文件中通過<plug-in>註冊。

4.4.8 data-sources

         與數據獲取層架起一座橋樑。

4.4.9 rolling your own

4.4.10 一個Struts配置文件框架

4.5 應用程序資源文件

         Struts框架爲每一個用戶維護一個標準的Locale對象(Java.Util.Locale)。應用程序資源文件的缺省名稱是通過在web.xml文件中爲ActionServlet初始化application參數。這個參數沒有缺省值,必需爲這個參數賦值才能使用Struts的ResouceBundle。

         使用ant可以將資源文件從源文件樹拷貝到二進制類目錄下。

4.6 ant build文件

4.7 配置Struts的核心組件

4.7.1 安裝Java和Java Servlet容器

         Struts發佈版本中包含的文檔,有配置各種servlet容器的技術說明。

4.7.2 安裝開發環境

         可以使用jEdit和jEdit的ant插件。

4.7.3 安裝Struts核心文件

         Struts的發佈版本包含了部署Struts的所有文件。

         檢查單:

n  下載並解壓Struts發佈版本

n  將所有的jar包拷貝的/WEB-INF/lib/下

n  將所有的tld文件拷貝到/WEB-INF/下

n  將所有的xml文件拷貝到/WEB-INF/下

n  創建部署描述子

n  創建Struts配置文件

n  創建消息資源bundle

n  創建ant build文件

4.8 配置Tiles框架

         Tiles框架是Struts的可選組件,是強大的頁面組裝工具。

         Tiles檢查單:

n  將struts-tiles.tld和tiles-config.dtd文件從Struts的lib目錄拷貝到/WEB-INF/目錄

n  將以下片段插入到web.xml文件中

<taglib>

<taglib-uri>/tags/tiles</taglib-uri>

<taglib-location>/WEB-INF/tiles.tld</taglib-location>

</taglib>

n  將空的tiles-defs.xml文件拷貝到/WEB-INF/目錄,格式如下:

<!DOCTYPE tiles-definitions PUBLIC

"-//Apache Software Foundation//DTD Tiles Configuration//EN"

"http://jakarta.apache.org/struts/dtds/tiles-config.dtd">

<tiles-definitions>

<!-- skeleton definition

<definition

name="${name}"

path="${path}">

<put

name="${name}"

value="${value}"/>

</definition>

end blank definition -->

</tiles-definitions>

n  在struts-config.xml文件的</struts-config>的結束元素之前加入<plug-in>元素:

<plug-in className="org.apache.struts.tiles.TilesPlugin" >

<set-property

property="definitions-config"

value="/WEB-INF/tiles-defs.xml" />

</plug-in>

4.9 配置StrutsValidator

         Struts Validator也是Struts的一個可選組件。

         配置Validator的檢查單:

n  struts-validator.tld和validator-rules.xml文件拷貝到/WEB-INF/目錄

n  將以下片段拷貝到web.xml文件:

<taglib>

<taglib-uri>/tags/validator</taglib-uri>

<taglib-location>/WEB-INF/struts-validator.tld</taglib-location>

</taglib>

n  在/WEB-INF/目錄下創建空白的validations.xml:

<form-validation>

<formset>

<!-- skeleton form

<form name="${}">

<field

property="${}"

depends="${}">

<arg0 key="${}"/>

</field>

</form>

end skeleton form -->

</formset>

</form-validation>

n  在struts-config.xml文件的</struts-config>元素前添加<plug-in>元素:

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">

<set-property

property="pathnames"

value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>

</plug-in>

4.10 從Struts Blank應用程序開始

         build.xml文件中可能引用了您的機器中沒有的文件:

         <property name=" jdbc20ext.jar"

value="/javasoft/lib/jdbc2_0-stdext.jar"/>

<property name="servlet.jar"

value="/javasoft/lib/servlet.jar"/>

<property name="distpath.project"

value="/projects/lib"/>

jdbc2_0-stdext.jar和servlet.jar是創建JavaDocs所需要的。

n  容器中應該包含servlet.jar文件

n  Struts的發佈版本中包含jdbc2_0-stdext.jar,很多容器(如Tomcat)中也包含。

4.11 配置模塊化應用程序

4.11.1 分治法

         每個模塊使用自己的struts-config.xml配置文件

4.11.2 頁面前綴

4.11.3 Retrofitting a configuration

4.12 共享Struts的JAR包

         Struts的JAR包可以被容器中的所有Struts應用共享。

第二部分 Raising your framework

第五章   處理ActionForms

5.1 吃進去的是草,擠出來的是奶

         Struts包含了一些JSP標籤,可以用來書寫動態的HTML控件。如同很多標籤庫一樣,Struts標籤也是同JavaBeans一起工作。每一個JSP標籤都有一個property屬性,提供bean中的一個property的名稱。JavaBean的這個property的值用來作爲控件的值。

5.1.1 ActionForm需求

         如果要使用ActionForm來驗證輸入,則必需實現validate方法。

         如果要初始化properties,則必需實現reset方法,用以在獲取ActionForm的properties的值之前調用。

5.2 ActionForm的多重功能

5.2.1 ActionForm作爲域捕獲器

         Struts使用ActionForms來彌補HTML和HTTP的缺點。

5.2.2 ActionForm作爲數據緩衝

         ActionForm並不是輸入的目的地,只是驗證和傳輸前的緩衝區。

5.2.3 ActionForm作爲數據驗證器

         ActionForm的validate方法是一個擴展點,在這裏你可以調用業務層方法來驗證輸入。

5.2.4 ActionForm作爲類型轉換器

         ActionForm的properties只能是String或boolean類型。

5.2.5 ActionForm作爲對象傳輸者

5.2.6 ActionForm作爲火牆

5.3 ActionForm設計效果

n  與業務層的bean具有相同的property名稱

n  最小化自定義的代碼

n  封裝helper方法

n  包含其他JavaBeans

5.3.1 ActionForms可能會共享名稱

5.3.2 ActionForms可以最小化自定義的代碼

5.3.3 ActionForms可以封裝helpers

5.3.4 ActionForms可以嵌套其他beans

<html:text property="values.telephoneText" size="14" maxlength="14"/>

等同於

aForm.getValues().getTelephoneText()

瀏覽器端會這樣傳輸數據:

values.telephoneText=555-1234

自動獲取機制會這樣取值:

aForm.getValues().setTelephoneText(

(String) request.getAttribute(valueBean.telephoneText);

5.4 ActionForm支持

5.4.1 map-backed ActionForms

         在ActionForm中可以這樣調用方法來獲取Map中的記錄:

         public void setValue(String key, Object value)

public Object getValue(String key)

在JSP中:

<html:text property="value(key)"/>

<bean:write name="formBean" property="value(key)"/>

5.4.2 DynaActionForm

         使用DynaActionForm,可以通過Struts的配置文件指定JavaBean的properties。

5.5 ActionForm的疑問

5.5.1 爲什麼ActionForm不直接就是一個Map?

5.5.2 爲什麼ActionForm不設計成普通的JavaBean?

5.5.3 爲什麼ActionForm不設計成接口?

5.6 對ActionForms的反思

5.6.1 實現一個業務層的接口

5.6.2 嵌套一個mutable的值對象

5.6.3 設置一個immutable的值對象

5.6.4 設置一個mutable的值對象

5.6.5 使用一個工廠方法

5.6.6 傳遞一個Map

         BeanUtils

5.6.7 通過反射傳遞值

5.6.8 使用適配器類

5.7 BaseForm

         這個類處理區域化,分派控制,管理自動計算等。

5.7.1 SessionLocale

         缺省情況下,ActionServlet會在每個用戶的session對象中自動創建一個locale對象。SessionLocale相關的方法可以用來管理這個對象。

5.7.2 分派

5.7.3 自動計算值

         處理數據轉換。可以在ActionForm和Bean之間轉換,以及將ActionForm中的值轉換成Map。

5.7.4 BaseMapForm

第六章   使用ActionForwards

6.1 ActionForwards做什麼?

         理想情況下ActionForwads應該在程序的每一個入口被用到—任何鏈接到另外一個頁面的地方。

6.2 ActionForwards如何工作?

         基類具有四個屬性:name,path,redirect,className。

6.2.1 forward與redirect

n  Forward保存request中的所有內容和request上下文。

n  Redirect只是web客戶端重新創建一個request。

轉發Requests

Java Servlet容器具有一個內置的機制,使request可以傳遞給另一個組件,叫做轉發。

重定向Requests

當ActionForward的redirect屬性設置爲true時,ActionServlet發送一個HTTP響應,高速瀏覽器重新提交一個請求給這個path。Request中的原始參數不會保留,request上下文會消失。

6.3 Global和Local Forwards

n  Global ActionForwads對應用程序中的所有Action都是可用的。

n  Local ActionForwards在ActionMapping中定義,只對從這個ActionMapping中調用的Action可用。

Global都應該定義成常量。Scaffold包中定義了一些常用的常量。

6.4 運行時參數

         有兩個地方可以改變ActionForwad的查詢組件。

6.4.1 在頁面中增加參數

         可以在<html:link>標籤中增加參數,例如:

         <html:link forward="article" paramId="key" paramProperty="key" name="articleForm">

<bean:write name="articleForm" property="name">

</html:link>

6.4.2 在Action中增加參數

         ConvertUtils提供了addParam方法。

6.5 動態的Forwards

         可以動態創建ActionForward對象,給它設定參數。

6.6 爲什麼地址欄不改變?

         要改變的話,只能redirect。

6.7 打造自己的ActionForward

         在Struts1.0中,要在web.xml文件中配置,在Struts1.1中,要配置Struts配置文件。

第七章   使用ActionMappings進行設計

7.1 進入ActionMappings

7.1.1 ActionMapping bean

         ActionMappings用來擴展Action對象而不是Action類。

7.1.2 ActionMappings目錄

         ActionMappings代表了Struts應用的核心設計。

7.2      ActionMapping屬性

7.2.1 path屬性

         ActionMapping的虛擬引用。

7.2.2 forward屬性

         如果forward屬性被指定了,則request不會傳遞給Action,而是調用RequestDispather.forward。

7.2.3 include屬性

         與forward同時使用。這兩個屬性與type屬性是互斥的。

7.2.4 type屬性

         一個Action類可以被多個actionMapping使用。

7.2.5 className屬性

         指定自定義的ActionMapping子類的qualified名稱。

7.2.6 name屬性

         Form bean的邏輯名稱。

7.2.7 roles屬性

         一組逗號分隔的role列表,這些roles可以訪問這個ActionMapping對象。

7.2.8 scope屬性

         設置ActionForm的範圍,缺省是session範圍的。

7.2.9 validate屬性

         如果validate設置爲true,ActionServlet會調用ActionForm的validate方法,如果validate返回false,則request被轉發到input指定的資源。

7.2.10 input屬性

         Struts1.1中input屬性可以指定爲一個ActionForward的名稱。如果要在input屬性使用ActionForward,要爲controller屬性的inputForward設成true。

7.2.11 parameter屬性

         ResourceUtils提供方法來加載一個properties文件。

7.2.12 attribute屬性

         在同一個上下文環境中使用兩份相同的ActionForm時,可以使用attribute屬性命名另外一個。

7.2.13 prefix和suffix屬性

         如同attribute,如果前綴是a,Formbean名爲bean,則aBean=。。。和bean=。。。一樣。

7.2.14 unkown ActionMapping

         處理404。

7.3 嵌套組件

7.3.1 Local Forwards

         先檢查local forwards,再檢查global forwards,如果都沒有,則返回null。

7.3.2 Local exceptions

         可以爲ActionMapping指定特定的ExceptionHandler。

7.4 打造自己的ActionMapping

         框架提供了兩個基礎的ActionMapping類,SessionActionMapping和RequestActionMapping。如果使用SessionActionMapping,則scope默認爲session。

第八章   使用Action對象

8.1 準備,就緒,開始

         Actions是Struts框架中最靈活的類。

         Actions的核心職責:

n  訪問業務層

n  爲表示層準備業務對象

n  處理兩個層之間出現的數據錯誤

8.2 使用Action對象

8.2.1 Actions是什麼?

         如同servlet一樣,Action是多線程的,一個Action類只有一個對象在應用中被使用。

         Actions是線程安全的,如果要繼承Action,在自己的Action類中不能在多個方法中共用屬性,所有的值都要通過參數傳遞來保證線程安全。

8.2.2 Actions什麼時候被調用?

         當需要Action時,ActionServlet會通過Action的perform或execute方法來調用。

8.2.3 Actions做什麼?

         一個典型的Action的通用職責:

n  驗證先決條件或斷言

n  調用任何需要的業務層方法

n  檢測任何處理錯誤

n  路由控制到合適的視圖

避免把業務邏輯放在Action類中是很重要的。

Struts消息可以接受最多4個參數。

在Struts1.1中可以使用更靈活的消息標籤:

<logic:messagesPresent>

<UL>

<html:messages id="error">

<LI><bean:write name="error"/></LI>

</html:messages>

</UL>

</logic:messagesPresent>

在Struts1.1中消息和error可以分別傳遞,以使用不同的樣式,使用方法同error:

saveMessages

ActionMessage

8.2.4 Action是什麼樣子?

8.3 標準的Actions

8.3.1 標準的bridge Action類

         用來集成Struts和應用程序中的其他Servlets。

         ForwardAction

         ForwardAction只是簡單地把控制轉發給其他資源,可以是任意具有URI的資源。

         IncludeAction

         當指定的servlet完成後,可以返回控制。

8.3.2 標準的base Action類

         BaseAction(Scaffold)

         DispatchAction

         LookupDispatchAction

         SwitchAction

                  SwitchAction可以切換到另外一個模塊,並把控制轉發到那個模塊的path。

8.4 Chaining Actions

8.4.1 Starting fresh

8.5 Scaffold Actions

         所有的標準的Scaffold Actions都繼承自BaseAction。

8.5.1 Forward-only Actions

         這樣的Action類只是一個簡單的dispatcher。

         SuccessAction

         RelayAction

適應於同一個頁面有多個Submit按鈕,而且使用不同的ActionMapping的情況,使用的時候要在頁面設置一個參數。

         ParameterAction

                   轉發的時候還傳遞參數。

         FindForwardAction

8.5.2 Helper Actions

         BaseHelperAction

         ProcessAction

         ExistsAttributeAction

         RemoveAttributeAction

8.6 Base View Actions

         Struts框架支持Action創建response。你可以創建自己的View Action來產生動態圖片,創建PDFs,使用XSL樣式表合併XML等。

8.7 Helper Action技術

8.7.1 可選轉發技術

         首先檢查特定的ActionForward存在,如果不存在,則忽略可選的行爲。

8.7.2 Calling ahead

8.7.3 捕獲chained異常

8.7.4 靈巧的錯誤轉發

8.7.5 確認success

         ProcessResult類。

8.7.6 切換視圖

8.7.7 反射方法

8.7.8 反射類

8.8 使用靈巧的轉發

第九章   擴展ActionServlet

9.1 Where is the beef?

         大多數情況下,ActionServlet不需要被繼承,直接使用應該可以滿足需求。

         ActionServlet的擴展點都是通過plugin的,而不是繼承。

9.1.1 Servlet的三人幫

         在所有的可插入的(Pluggable)組件中,RequestProcessor組件是最強大的。

         RequestProcessor處理的一個高層問題是異常處理,Exception類可以註冊一個Handler如果是沒有註冊的Exception,RequestProcessor使用ExceptionHandler處理。

         很多應用程序需要訪問自己特殊的資源,爲方便在Struts中初始化自定義的資源,可以向Controller註冊一個PlugIn Action。控制器會在啓動的時候調用這個Action的init方法,關閉的時候調用這個Action的destroy方法。

9.2 RequestProcessor

         當一個request進來的時候,servlet選擇應用程序模塊,並把request交給RequestProcessor,每一個模塊都可以加載自己的RequestProcessor的子類,或者直接使用RequestProcessor。

         RequestProcessor提供了一些可以重寫的方法,用來擴展RequestProcessor。

9.2.1 process方法

         可以擴展的方法都是在process方法中調用的,process方法的職責是處理HttpServletRequest和產生相應的HttpServletResponse。

         爲創建響應,典型的,processActionForward方法會將request發送給JSP頁面或其他資源。

9.2.2 processRoles方法

         RequestProcessor的擴展點中,最有可能被完全重寫的方法就是processRoles。processRoles的職責就是檢查用戶是否被允許訪問Action。缺省的行爲是使用標準的Java Security API。

         缺省的行爲是,通過request的參數,用ActionMapping中指定的role列表和IsUserInRole方法,如果用戶屬於指定的roles,則驗證通過。

         通過重寫processRoles,可以容易地將此特性適應於合適的基於應用程序的安全模式。

9.3 ExceptionHandler

         ActionServlet會捕獲所有異常,如果捕獲了一個異常,它首先檢查你是否已經爲這個異常註冊了handler,先檢查local的,再檢查global的。

         如果ActionServlet沒有找到handler,將重新拋出這個異常。

         ExceptionHandler可以在Struts配置文件中註冊,如果<exception>元素的path屬性沒有指定,則使用ActionMapping的input屬性。
         <exception>元素的屬性包含handler和className,可以用來指定自定義的ExceptionHandler,也可以爲這個handler指定一個自定義的配置bean。
         自定義的handler必需繼承自缺省的ExceptionHandler。入口方法是execute。

         ExceptionConfig bean表示從Struts配置文件中讀取的原始的<exception>元素。如果需要其他屬性,可以繼承ExceptionConfig類,在配置文件中通過<set-property>初始化屬性。

9.4 PlugIn

         允許一個Action實現PlugIn接口的init和destroy方法。

第二部分 構建自己的頁面

第十章   顯示動態內容

10.1 Tag-you’re it

         Struts發佈版本包含了一組預先寫好的JSP標籤,可以把Struts框架和JSP標籤結合起來。

         JSTL。

10.1.1 JSP標籤有什麼好處?

服務器端頁面

有很多服務器端頁面:ActionServer Pages,ColdFusion Pages,PHP,Velocity模板,JSP等。

10.1.2 Struts與JSTL

         JSTL的實現有很多與Struts標籤庫重疊的地方。JSTL需要容器支持Servlet2.3和JSP1.2,如Tomcat 4,Resin 2。

         JSTL並沒有消除自定義標籤擴展的需求。

         JSTL表達式語言

         JSTL提供的表達式語言(EL)來替換scriplets。

10.1.3 Struts標籤與MVC

         Struts標籤提供了所有應用程序需要的來創建MVC式的表示層的所有功能。

10.2 使用標籤擴展

10.2.1 怎樣書寫標籤擴展?

         JSP標籤是用Java語言使用標籤擴展API書寫的。這些類解析XML格式的tag,使用tag的屬性作爲類的方法的參數。

         與JSP的base標籤相對應,有一個BaseTag類,BaseTag類擴展了一個API類,BaseSupport,重寫了doStartTag方法。

10.2.2 如何安裝標籤擴展?

1. 安裝JAR和TLD文件。

2. 更新web.xml文件。

3. 在頁面中引入新的taglib文件。

10.2.3 標籤擴展不是什麼?

n  標籤擴展不能被所有HTML可視化編輯器支持

n  不是所有的scriptlet都能被的標籤擴展替換

n  標籤擴展不是JavaServer Faces

10.3 Struts標籤庫

         Struts發佈版本包含4個關鍵的標籤庫:bean,html,logic和nesting。html中幾乎所有的標籤都依賴於Struts框架,其他三個庫中幾乎所有的標籤都不依賴於Struts框架。

10.3.1 Struts標籤的共同特性

自動定位範圍

在尋找對象的時候,Struts標籤會自動檢查標準上下文—page,request,session和application,使用找到的第一個實例。

共同屬性名稱

         id,name,property,scope

擴展的語法

         嵌套引用,如:foo.bar.baz

運行時表達式

         標籤的屬性中可以使用scriptlet。

同用的錯誤處理

10.3.2 bean標籤

         11個bean標籤(cookie,define,header,include,message,page,parameter,resource,size,struts,write)可以用來:

n  從HTTP頭、request參數,cookie,或者任何範圍內存在的對象創建腳本變量

n  從response向另外一個request創建一個新的bean,從應用程序資源或Struts配置對象

n  確定一個Collection或Map的大小

n  自動地從應用程序資源文件爲當前用戶創建區域或消息

n  書寫任何可用的bean的屬性

只有message和struts依賴於Struts框架,其他標籤可以應用於任何應用程序。

Bean標籤最佳實踐

最常用的標籤<bean:write>和<bean:message>。

10.3.3 html標籤

Html標籤和scriplet版本的區別:

n  Scriplet要求bean要在jsp中先定義後使用,html標籤沒有這個要求。

n  缺省情況下,Struts標籤在整個form中使用,不需要爲每一個控件指定。

共同屬性

name:ActionForm或JavaBean的名稱

on*:事件處理

accessKey:按下賦給元素的accessKey使元素獲得焦點

tabindex

style

StyleClass

10.3.4 logic標籤

包含三個邏輯標籤:evaluation標籤,控制流標籤,和重複標籤。

Evaluation標籤—共同屬性

Cookie,header,parameter,name,property

控制流標籤

在index.jsp中可以使用:

<%@ taglib uri="/tags/struts-logic" prefix="logic" %>

<logic:forward name="welcome"/>

Repeat標籤

<logic:iterate>

10.4 使用Struts的JSP標籤

10.4.1 Struts標籤團隊

         各類標籤庫聯合使用可以達到一些效果。

10.4.2 基礎

聲明一個Form

<html:form></html:form>

產生html控件元素

使用ActionForm bean的property。

選擇radio按鈕

         Property相同,value設置好,如果ActionForm與html:radio的property值相同的property的value相同,則checked。

過濾HTML

<bean:write>標籤自動過濾特殊字符,如果要取消,則把filter屬性設置成false。

清除密碼

Redisplay屬性設置成false,則密碼一直以空的形式出現。

使用事務性標誌

解決重複提交問題。

<html:form>自動使用同步標誌,在Action端可以通過調用saveToken(request)。

對options使用集合

         從Struts1.1開始,可以使用LabelValueBean。

對checkbox使用數組

         Mutibox控件。

區域化labels

         <bean:message>

區域化options

區域化集合

10.4.3 技巧

使用ImageButtonBean表示ImageButton

使用bean標籤創建自定義控件

使用數組捕獲重複的參數

使用<bean:size>測試集合的大小

迭代集合的一部分

暴露迭代的下標

使用嵌套的<present>和<notEmpty>測試bean屬性

爲穩定的option list使用application範圍的對象

使用rewrite爲樣式表,javascripts和其他資產產生URLs

使用JSP標籤產生JavaScript

         大部分web開發者都依賴於javascript來創建表示層的核心特性,Struts開發者也不例外。

使用<bean:write>從bean產生javascript

重命名submit按鈕來避免javascript衝突

使用無form按鈕

使用action作爲input屬性來重新創建依賴的對象

使用動態的form Actions

使用可選擇的message標籤

         <logic:messagesPresent>

<UL>

<html:messages id="error">

<LI><bean:write name="error"/></LI>

</html:messages>

</UL>

</logic:messagesPresent>

可以指定某個消息顯示在某個控件的旁邊。

10.4.4 成功的控制

10.5 可選的視圖

10.5.1 Struts與JSP

         Struts本身並不處理JSP,而是容器負責處理。

10.5.2 Servlet上下文

         三個標準的上下文:request,session,application。

10.5.3 超越JSP

         使用Struts可以擴展XSLT和Velocity。

第十一章            使用Tiles開發應用程序

11.1 調整佈局

可用性是當今web應用設計的一個主要關注點,而一致性是可用性的一個主要成分。

11.1.1 使用動態模板分層

         將顯示與內容分離的一個方法是使用動態的JSP include。JSP規範提供了靜態和動態的include。動態include的標準JSP動作是<jsp:include>。

         我們利用動態include的方法是,把服務器端頁面分解成多個片段(fragment),每一個片段負責自己的一部分工作。背景模板可以設置缺省格式和佈局,可以在運行時包含include來顯示內容。動態的include將被包含的頁面的輸出展開到原始頁面。Tiles框架使用jsp動作的一種更高級的形式。在Tiles應用程序中,背景、佈局、模板通常定義頭部、菜單體、內容和尾部的位置。其他頁面被包含進來來填充這些位置。如果頭部變化,只需要改變模板文件,這個變化會自動地體現在包含模板的頁面。HTML的標準組件,如CSS,可以很好地與動態模板工作。

11.1.2 模板的效果

         每一項技術都有一些折衷,使用模板的效果如下:

n  JSP包含技術已經是良好建立而且可靠,趨向於在大型應用裏也表現良好。包含動態模板的技術是核心Java Servlet API的一部分。

n  大部分的容器都爲JSP和象servlet include這樣特性做了優化。

n  被包含的頁面通常輸出HTML片段,不能用標準的HTML編輯器維護。

n  大部分的站點都在源代碼變化的時候重新編譯JSP。模板創建了更多的頁面,也創建了更多的變化的可能性。

n  模板實際上重用了代碼。

11.1.3 使用模板

         一些術語:

         動態元素(Dynamic element):JSP翻譯器識別出的JSP的一部分,包括action,directive,expression,JSP標籤或者scriplet。

         模板數據(Template data):沒有被JSP翻譯器識別出的JSP的一部分,通常是標記和可見的文本。

         模板頁(Template page):一個包含另一個頁,或被另一個頁包含的JSP。

         模板文件(Template file):被一個模板頁面包含的靜態文件或JSP。

         Tile:Template file的縮寫。

         Layout:關於Tiles如何定位於頁面的描述。

         Tiles:一個使模板和佈局更容易和更強大的框架。

         定義(Definition):一個Tiles特性,它允許一個佈局被指定爲一個模板頁或JavaBean。定義可以用XML文檔來描述。

11.1.4 結合模板,Tiles和Struts

         Tiles框架通過使用簡單有效的標籤庫使模板佈局的使用更加簡單。

         通常情況下,一個JSP模板系統使用一個模板文件作爲佈局,另一個模板文件作爲填充組件。

11.2 構建一個佈局模板

         構建任何一個佈局的第一步是識別組件的組成部分。對於一個經典的web頁面,組成部分有header,menu,body,footer。創建一個這樣佈局的模板頁很簡單:

1.       打開一個新的JSP頁面。

2.       引入Tiles標籤庫。

3.       創建一個HTML表格,使其cells與模板頁的骨架匹配。

4.       使用一個Tiles JSP標籤(<tiles:insert>)爲佈局的每一個部分命名。

我們每創建一個cell來放置佈局組件,我們都放置一個JSP標籤(<tiles:insert attribute=”aName”>。這使我們能夠不斷地使用這樣的佈局,每一次只要爲tiles傳遞不同的路徑即可。

我們的經典佈局可以構造成一個完整的獨立的模板頁,只要再加上HTML標記的其餘部分。

11.2.1 說了半天,到底什麼是tile?

         嚴格地說,tile是JSP頁面的一個矩形區域。

         Tile對象支持一些重要的特性,如參數和定義。

         參數

         Tile可以在運行時通過參數或屬性的形式接受變量信息。Tiles參數通常叫做屬性(Attributes),以區別於request的參數。Tile屬性在插入tile時定義,而且只對這個tile可見。Tile的attributes可以是字符串或其他類型。

         定義

         定義存儲一組attributes,使一個屏幕描述成爲一個擁有唯一表示的可辯別的對象。聲明一個基類屏幕定義,然後派生這個基類屏幕定義以創建其他屏幕定義。

11.2.2 部署一個Tiles模板

         <tiles:insert>

                   <tiles:put/>

         </tiles:insert>

11.2.3 增加樣式表

         使用<html:base>與<html:rewrite>。

11.2.4 模板與MVC

         可以重構既存系統得到一個MVC模板系統。

11.3 Tiles定義

11.3.1 聲明定義

         一個定義需要如下信息:

n  基礎模板文件的路徑

n  傳遞給模板的0個或多個屬性列表

n  定義的一個標識符

僅通過向特性列表中增加identity,會增加一些功能:

n  可以在部署的時候通過額外的或替換的屬性來重載定義。

n  可以擴展定義,把一個定義作爲另一個的基礎。

n  可以重用定義,把定義存儲在JSP中或從XML文檔加載。

n  定義可以是Struts ActionForward的目標。

11.3.2 JSP聲明

         用JSP中使用Tiles定義的過程包括:

n  用JSP聲明一個定義

n  部署JSP聲明的定義

n  重載定義

n  使用JSPs重用定義

11.3.3 配置文件聲明

         每一個定義通過name屬性標識。

11.4 Tiles屬性

         Tiles存儲它的屬性在自己的上下文中。

11.4.1 useAttribute

         <tiles:useAttribute name="myAttribute" />或

         <tiles:useAttribute attributeName="anAttribute" name="myAttribute" />

         這樣聲明之後,可以這樣使用:

         <bean:write name="myAttribute" />

11.4.2 importAttribute

         <tiles:importAttribute>將所有tiles屬性導入到page上下文。

11.4.3 put

         <tiles:put>將一個值與一個tiles屬性關聯。

11.4.4 putList與add

         Tiles的屬性可以是java.util.List類型。

11.5 將應用程序移植到Tiles

         將應用程序移植到Tiles與重構的“抽取方法”相似。

11.5.1 安裝Tiles框架

         首先,備份所有東西。

         Tiles與Struts1.1集成在一起的。

11.5.2 測試缺省配置

         將web.xml文件中debug和detail參數設置成2。查看所有的錯誤信息。

11.5.3 審查頁面

         識別佈局。

         識別Tiles

         命名候選組件

11.5.4 使用<tiles:insert>重構頁面

11.5.5 抽取<tiles:insert>到定義

11.5.6 規範基礎佈局

11.5.7 將定義細化到基類和擴展類

11.5.8 開發一個規程

         經過幾個頁面的重構,應該可以開發一個規程。前幾個頁面是根據應用程序的流程,到後來就可以根據規程one by one進行重構。

11.5.9 管理移植

第十二章            驗證用戶輸入

12.1 見文知意

         一個健壯的應用程序檢查所有的輸入,守衛所有可預見的錯誤。

12.1.1 不能拒絕輸入

         缺省情況下,HTML元素接受用戶輸入的所有內容。可以使用javascript來控制,但是用戶可以關閉javascript功能。使用業務層驗證數據不合適,特別是對於分佈式系統,業務對象可能在遠程,使用業務對象來驗證成本比較高。

12.1.2 web層驗證

         在一個無模型的、分佈式環境下,我們需要驗證規程做如下事情:

n  要求一些字段必需有值

n  確認給定的值屬於預期的模式或範圍

n  一次性檢查整個form並返回一個message列表

n  比較多個字段的值

n  返回原始的輸入用來糾正

n  當需要顯示消息時,顯示區域化的消息

n  如果javascript被禁用,要執行服務器端的驗證

n  鬆散耦合:驗證的規則應該和標記語言或java語言分離。

n  客戶端驗證:客戶端驗證是不安全的。雖然不能依賴於客戶端驗證,但客戶端驗證仍然是很有用的,因爲可以使用戶獲得即時的反饋。

12.1.3 驗證器的效果

         使用Jakarta Commons Validator的效果有:

n  驗證器是一個框架組件,可以滿足上一節提到的需求。

n  驗證器通過XML文件配置,來對form的輸入域產生驗證規則。

n  驗證器定義的規則也是通過XML文件配置。

n  提供了對於基本類型的驗證器,如果需要可以創建自己的驗證器。

n  正則表達式可以提供基於模式的驗證,如郵編和電話號碼。

n  支持多頁面的和區域化的驗證。

使用Jakarta Commons Validator有以下好處:

n  優化資源的使用:提供Javascript驗證,只要用戶沒有禁用,服務器端驗證是得到保證的。

n  單點維護:服務器端和客戶端驗證通過同一個配置產生。

n  可擴展性:自定義驗證可以定義爲正則表達式或者java代碼。

n  可維護性:單獨維護,與標記語言或java代碼鬆散耦合。

n  區域化:提供區域化驗證。

n  與Struts集成:缺省情況下,驗證與Struts共享信息資源文件。

n  服務器端驗證部署容易:只要使自己的ActionForm從ValidatorForm或ValidatorActionForm繼承。

n  客戶端驗證部署容易:只要加上一個JSP標籤來產生驗證腳本和使用這個腳本來提交form。

n  易配置:驗證器使用XML文件配置,如同web部署描述子和Struts配置文件一樣。

也有一些缺點:

n  無模型的客戶端驗證:產生的javascript是無模型的。

n  依賴性:頁面標記、ActionForm及驗證器和Struts配置文件要保持一致。

n  缺乏數據轉換:包不提供數據轉換。

12.2 Struts驗證器總覽

         組成Struts驗證器的各部分:

         Validators:處理基本的和其他公共的類型。基本的驗證包括:required,mask(匹配正則表達式),miniLength,maxLength,基本類型,date,email和creditCard。也可以定義自定義驗證器。

         Resource bundle:默認情況下共享Struts的消息。

         XML配置文件:定義form集合和字段的驗證。

         JSP標籤:爲給定的form名或acion路徑產生javascript驗證。

         ValidatorForm:根據form bean的name自動驗證屬性。

         ValidatorActionForm:根據Action路徑自動驗證。

         驗證器提供了一些基本的驗證,如果滿足不了可以打造自己的驗證器並插入到包中。應用程序需要的驗證器可以在xml文件中配置,通常叫做alidation.xml,驗證規則也可以單獨放在一個文件中,通常叫做validator-rules.xml。

         Validator-rules文件有一個<form>元素,與Struts的<form-bean>對應,<form>元素有<field>子元素。每一個<field>可以指定它必需通過一個或多個驗證器才能成功。如果驗證失敗,可以返回資源文件的key,可以帶參數。如果使用客戶端驗證,可以在javascript window顯示相同的消息。

         爲使服務器端驗證可用,只需從驗證器的基類擴展自己的ActionForm,

12.2.1 Logon實例

Validator-rules.xml

Validator.xml

JSP標籤/login.jsp

Validate方法

         要繼承ValidatorForm,並移除validate方法。

12.3 基本的驗證器

         Struts驗證器提供了14種基本的驗證器。

         required:

         mask:要驗證的字段滿足一個mask屬性指定的正則表達式。

         range:

         maxLength:

         minLength:

         byte,short,integr,long,float,double

         date:

         creditCard:

         email:

12.4 Resource Bundle

12.4.1 缺省的bundle

         Struts Bundle通過部署描述子來配置。

12.4.2 缺省的驗證器消息

         規範是在驗證器的name前加errors.前綴,如果required驗證器的缺省消息是errors.required。

         # Struts Validator Basic Error Messages

errors.required={0} is required.

errors.minlength={0} cannot be less than {1} characters.

errors.maxlength={0} cannot be greater than {1} characters.

errors.invalid={0} is invalid.

errors.byte={0} must be a byte.

errors.short={0} must be a short.

errors.integer={0} must be an integer.

errors.long={0} must be a long.

errors.float={0} must be a float.

errors.double={0} must be a double.

errors.date={0} is not a date.

errors.range={0} is not in the range {1} through {2}.

errors.creditcard={0} is not a valid credit card number.

errors.email={0} is not a valid e-mail address.

12.4.3 自定義驗證器消息

12.5 配置文件

         在Struts1.1中,驗證器配置文件的路徑在Struts配置文件中指定。

12.6 驗證器JSP標籤

         <logic:messagePresent>

         <logic:messages>

12.7 ValidatorForm和ValidatorActionForm

         可以先用驗證框架驗證,再用自己的驗證。

12.8 區域化驗證

         Validator配置文件包含一個formset元素,formset是一個擁有同一個區域設置的forms的集合。

12.9 可插入的驗證器(Pluggable Validator)

12.9.1 創建一個可插入的驗證器

         兩步:

n  在一個Java類中創建一個方法來處理服務器端驗證。

n  爲驗證器更新validator-rules.xml。如果驗證器有客戶端驗證,將javascript作爲rules的一部分。

12.10 技巧

12.10.1 多頁驗證

         很多開發者喜歡使用嚮導式表單。一些開發者爲每一個使用一個不同的表單,還有一些開發者爲這些頁使用同一個表單,每次只顯示錶單的一部分。

         對於使用一個大表單的形式,Struts驗證器提供了page屬性。

12.10.2 取消按鈕

         Struts驗證器提供了一個bCancel Javascript變量。

12.10.3 自定義消息

         使用mask驗證要提供自定義消息,以顯示更具體的提示消息。

12.10.4 關聯的字段

         通過定義自己的plug-in驗證器。

12.10.5 結合驗證器和validate方法

         使用plug-in驗證器,最好是這個驗證器能夠被重用,否則重寫validate方法即可。重寫的時候要確保調用了父類的validate方法以調用Struts框架的驗證器。

12.11 將應用程序移植到Struts驗證器

12.11.1 安裝驗證器框架

12.11.2 測試缺省配置

         將web.xml文件中的debug和detail設置爲2級,看看有沒有錯誤消息。

12.11.3 審查驗證

         審查validate方法,確定哪些可以有驗證框架實現,哪些由自定義驗證實現。

12.11.4 擴展ValidatorForm或者Scaffold BaseForm

         確保ActionForm從這兩個類中的一個繼承。

12.11.5 選擇一個驗證進行移植

12.11.6 添加formset,form和field元素

12.11.7 在ApplicationResources中添加新的記錄

12.11.8 調用Struts驗證器

         調用父類ValidatorForm進行驗證。

12.11.9 測試和重複進行

12.11.10 移除ActionForm子類

         如果validate方法只調用了父類的方法,可以將form-bean中的ActionForm換成父類。

第十三章            區域化內容

13.1 By any other name

         Struts框架讓開發者在單獨的文件中定義標籤和消息,稱作Resource Bundle(java.util.ResourceBundle)。Resource Bundle是Java國際化特性的一部分。Struts框架也是完全支持國際化的。

         Internationalization有時縮寫爲i18n,因爲在第一個字母i和最後一個字母n之間有18個字母。

         Struts在Java平臺的標準特性的基礎上構建國際化特性。

13.1.1 爲什麼要區域化?

         除了語言,日期、通貨、圖像都需要區域化。

13.1.2 Java國際化的工作原理

爲實現國際化,應用程序應該能夠:

n  區分不同的區域。

n  使用相同的可執行程序爲不同的區域顯示合適的標籤和消息。

n  對新的區域提供支持,而不需要修改可執行程序。

n  自動格式化對區域敏感的元素,如日期、通貨等,使其適合於給定的區域和語言。

Java通過三個關鍵類來滿足對國際化的支持:Locale,ResourceBundle和MessageFormat。

         Locale

         Java對國際化支持的絕對核心是Locale對象(java.util.Locale)。這個簡單的對象使你可以組合語言、國家和可選的變量進入單個Locale實體。語言和國家由ISO標準定義(ISO-3166,ISO-639)。例如:

         語言代碼         描述                   國家代碼         描述

         de                       德語                   CN                      中國

         es                        西班牙語         CA                       加拿大

         en                       英語                   DE                       德國

         fr                         法語                   FR                       法國

         ja                         日語                   IN                        印度

         jw                        爪哇語              US                       美利堅合衆國

         ko                        韓語                  

         zh                        漢語

        

         可選的變量通常用來表示方言,但是可以是任何對應用程序有用的代碼。Struts框架沒有使用variant字段。

         爲創建Locale對象,向構造函數傳遞語言和國家的代碼,如說法語的加拿大人的locale對象可以這樣創建:

         locale = new Locale(“fr”,”CA”);

         通常Locale對象會傳遞給工具方法,這個工具方法基於Locale對象的設置來格式化輸出。

         ResourceBundle

         爲支持另外一種Locale,只要爲這個Locale在bundle中增加一個資源文件。

         ResourceBundle是一個抽象類,有兩個基本的實現:ListResourceBundle和PropertyResourceBundle。

         PropertyResourceBundle類用來處理一組文本消息,在大多數Struts應用中都使用它。消息可以從一個properties文件中加載,通常通過調用一個靜態方法:

         message = ResourceBundle.getBundle(“application”,locale);

         如果找不到請求的locale,則使用默認的bundle。

         ListResourceBundle用來加載非String的對象。

         MessageFormat

         MessageFormat用來在運行時合併消息模板和可替換的參數。

13.2 Struts國際化組件

13.2.1 Session的Locale屬性

         所有標準的Java國際化的工具都是依賴於Locale對象,所以國際化的基礎就是爲每一個用戶維護一個Locale對象。

         缺省情況下,Struts會爲每一個用戶在他的session上下文環境中使用已知的key存儲一個Locale屬性。初識時,這個屬性設置爲服務器端的缺省區域。

13.2.2 MessageResources

         Struts提供了MessageResources類來獲取消息。Struts開發者很少直接調用這個對象,而是通過其他類來返回合適的消息。

         MessageResource的缺省實現是使用PropertyResourceBundle,但是其他實現可以使用XML文件或者SQL數據庫。

         典型地,消息通過JSP標籤或其他表示層系統來獲取。Action也可以通過調用MessageResources來準備區域化的消息。例如:

         Locale locale = (Locale) session.getAttribute(Action.LOCALE_KEY);

MessageResources messages = servlet.getResources();

String message = getMessage(locale,"important.message");

((messageForm) form).setMessage(message);

getMessage被重載了,它可以接受最多四個參數。

13.2.3 缺省的resource bundle

         每一個資源都是在第一次使用的時候從磁盤加載,然後在應用程序的聲明週期內一直保留在內存中。

         格式化消息

         由於使用標準的Java庫,格式化數字、日期、通貨的通用技術可以與Struts消息結合使用。

         顯示特殊字符

         Java編譯器和其他Java工具只能處理Latin-1(ISO 8859-1)或Unicode編碼的字符。爲幫助轉換不使用Latin-1系列字符的文件,JDK提供了一個工具native2ascii。

         也可以使用Java Internationalization and Localization Toolkit 2.0來做同樣的事情。這個工具包包含了很多對大規模翻譯文件很有用的工具。

13.2.4 ActionErrors

         每一個message都可以與form上的一個屬性關聯,這使開發者可以在屬性的附近顯示消息。

13.2.5 ActionMessages

         ActionMessage標籤提供了額外的功能,使開發者不用將標記語言與消息混在一起。

13.2.6 Locale-Sensitive JSP標籤

         Struts標籤庫包含了一些lcoale-sensitive標籤:

         bean:message

         bean:write

         html:errors

         html:html

         html:img

         html:image

         html:messages

         html:option

         html:button

         html:cancel

         html:checkbox

         html:file

         html:hidden

         html:mutibox

         html:password

         html:radio

         html:select

         html:submit

         html:text

         html:textarea

         html:form

         html:link

         圖像相關的標籤提供額外的key屬性來提供圖像和文本的雙重區域化。

         Locale-sensitive標籤的通用屬性:

         arg0,arg1,arg2,arg4:參數化替換值。[message write]

         bundle:應用程序範圍的bean的名稱,在這個bean下,包含我們消息的MessageResources存儲其中。[message image img write option errors messages]

         key:被請求的消息的消息key在消息資源中必需有一個對應的值。[message write image img option]

         locale:session範圍的bean的名稱,存儲着當前選擇的locale對象。

         altKey,titleKey:alt或title文本。[button cancel file hidden image img multibox password radio reset select submit text textarea]

         titleKey:沒有alt。[form link]

         pageKey,srcKey:指定圖像的的消息資源的key。可以是應用程序相對路徑或者URL。[image img]

         formatKey:提供一個格式化字符串的key,從資源總獲取消息。[write]

         <bean:message>

         更多地應用於HTML表單中。

         <bean:write>

         具有formatKey屬性,可以從resource bundle中讀取消息的模板。

         具有locale屬性,只是session範圍內的bean的名稱。

         <html:errors>和<html:messages>

         自動爲用戶的locale從資源bundle中打印消息。

         <html:html>

         根據用戶的locale對象,產生不同的結果,如

         <html:html>à<html lang=”en”>或者

         <html:html>à<html lang=”fr”>

         <html:image>和<html:img>

         在區域化image或image button的時候要考慮三點:

n  二進制圖像文件的的源

n  Image的alternate文本

n  元素的advisory title

<html:option>

對text屬性,可以指定一個key。

其他屬性

bundle,locale

13.3 區域化Struts應用程序

13.3.1 使區域化可用

         有三點:

n  Servlet的locale參數是否設置正確

n  缺省的application resource bundle參數是否設置正確

n  區域化的JSP頁面是否使用了<html:html>

設置locale servlet參數

         缺省情況下Struts對每一個用戶自動創建一個缺省的local對象,是否會自動創建取決於是否在web.xml文件中設置了ActionServlet的locale參數。

設置應用程序資源servlet參數

         設置ActionServlet的application參數。

13.3.2 使用框架Locale對象

         檢查用戶的Locale

         Locale locale = request.getSession().getAttribute(Action.LOCALE_KEY);

         如果Action繼承自BaseAction,可以直接使用:

         Locale locale = getLocale(request);

         改變用戶的Locale

         Locale對象是不可變的(immutable),必需使用一個新對象來替換。

         Locale locale = new Locale(myForm.getLanguage(),myForm.getCountry());

         HttpSession session = request.getSession(true);

         Session.setAttribute(Action.LOCALE_KEY);

         如果Action繼承自Scaffold包的BaseAction,則可以使用:

         Locale locale = new Locale(myForm.getLanguage(),myForm.getCountry());

         setLocale(request,locale);

         如果應用程序只對語言區域化,則國家參數可以傳遞一個空串。

         使用Struts的locale-sensitive組件

         Struts組件會自動獲取區域化消息。

13.3.3 在Properties文件中放置標籤和消息

         Properties文件中放置key-value對。

13.3.4 創建特定語言的Properties文件

         爲每一種locale創建一個文件。

13.3.5 在區域化組件中指定合適的key

         通過key獲取locale的標籤與消息。

13.3.6 與其他組件結合使用<bean:message>

         對於不提供內置區域化的組件,可以使用<bean:message>來提供區域化的消息。

13.4 區域化其他組件

13.4.1 區域化Struts驗證器

         如果需要額外的區域化驗證,例如,對郵編或電話號碼進行驗證,特定區域的form-set元素。

13.4.2 區域化Tiles

         可以爲每一個區域創建區域化的tiles配置文件。

13.4.3 區域化集合

         <html:options>

         MessageUtils

         <html:mutibox>

         MessageUtils.getLabelValueBean()

第十四章            在Struts中使用數據服務

14.1 Stepping Out

14.1.1 從模式的視角來看JDBC

         從模式的視角,JDBC驅動是集成層的一部分,而實際的數據庫存活在資源層。

         對於開發者來說,驅動和數據庫之間的交換是透明的。

         隱藏業務層

         JDBC驅動使用的driver:device或者說是façade模式,是一種你可以在集成任何數據服務時使用的策略。

         設計的目標是提供一個接口(或驅動),應用程序可以使用這個接口而無需知道隱藏在接口後面的數據服務。

14.1.2 引入數據服務

         通過一個實例。

         首先,使用Scaffold包中的StatementUtils和ResultSetUtils類連接JDBC數據庫服務。這一步很簡單,基準策略是使用反射和元數據將SQL ResultSet轉換成JavaBeans。

         接下來,我們走出數據庫黑盒,與Lucene連接起來。

         最後,我們表明嚮應用程序增加服務,如RSS,是多麼的容易。

14.2 探索業務層

14.2.1 Struts—引入自己的模型

         業務邏輯bean,即業務對象。

14.2.2 定義業務對象

         爲定義業務對象,必需首先隔離核心業務邏輯。

14.2.3 設計業務對象

         理想情況下,業務方法應該只接受和返回通常的Java類型,只拋出自己的一組異常。因此,業務邏輯bean應該:

n  代表程序的核心邏輯—它的API

n  可能的情況下,只接受和返回Java基礎類型和類

n  定義自己的異常類

n  對其他類暴露最小的依賴

業務邏輯對象不必遵守JavaBean的規範,但是遵守規範可以花費很少,取得甚多。

爲什麼要拋出自己的異常?首先,爲提供封裝。其次,爲提供控制。

14.2.4 設計效果

n  降低耦合,提高可維護性

n  引入附加層

n  提供簡單統一的接口

n  可能會隱藏低效

14.2.5 將業務對象與Action混合

         如果不使用業務層,會有一些Struts特定的結果:

n  直接在Action中書寫業務邏輯,隨着程序規模的增長,會變得難以擴展和維護。

n  在Action中實現的邏輯很難在Struts框架就以外使用,或者適當地使用測試工具,如JUnit。

n  數據訪問、錯誤處理和其他資源層代碼可能會在Actions之間重複,只能通過複製粘帖來複用。

n  關鍵元素,如SQL命令會被隱藏起來很難審查。

n  Actions會變成應用程序接口,促使開發者在Actions之間轉發請求。

n  當Actions變成API時,需要新的機制,要麼是中間查詢串,或者用Action檢查請求中間的信號量對象。

n  Actions會變得複雜,要從其他客戶端和其他Action處理業務邏輯請求。

n  代碼會變成意大利麪條。

14.2.6 一個簡單的例子

看一看Artimus示例應用程序的業務邏輯API。

Artimus—初始業務需求

n  存儲一篇文章的標題、作者和內容

n  以降序方式列出最新的文章(從新到舊)

n  通過標題、作者、內容或其他屬性來過濾和列出文章

Artimus—初始API

insert

searchLast

searchTitle

14.3 在Struts中使用ProcessBeans和JDBC

         有一些產品提供JavaBean和關係數據庫的ORM(Object-Relational Mapping)。ProcessBeans使用了很多這樣的技術:

n  封裝應用程序的功能性邏輯

n  表示交易的狀態,如購物車

n  避免使用web層的類

n  提供execute觸發方法,來引入具體行爲

此外,一個ProcessBean:

n  使用bulk setter從其他javabean產生自身

n  使用bulk populator向其他javabean拷貝值

ProcessBeans不是ORM的一個實現。並非封裝或隱藏SQL,ProcessBean包提供一個結構性的位置,在這裏你的查詢並得到一個JavaBeans的集合作爲返回值。它還從其他beans自動產生你的model beans,並從儘快地將數據從SQL的ResultSet移動到你的JavaBeans。

14.3.1 引入ProcessBeans

         如同ActionForm,ProcessBeans不必是數據庫表的直接表示。二者可能有交集,甚至很多屬性通常一樣,但這只是巧合,而非設計目標。

         更常見的是,ProcessBeans的屬性是幾個表的連接的列的集合,稱作邏輯視圖。

         ProcessBeans並不代表庫表,而是代表數據庫的邏輯視圖。哪些屬性屬於邏輯視圖,由業務API決定。

14.3.2 ProcessBeans作爲傳輸對象

         因爲ProcessBeans被用來將數據從一個層送往另一個層,可以把ProcessBeans看作是傳輸對象。一些傳輸對象是隻讀的,即immutable,這通常發生在EJB環境下,這種情況下,數據庫是遠程的,更新的代價很高。

14.3.3 產生ProcessBeans

         ProcessBean實際上是兩個接口,定義了兩個主要的簽名:

         public Object execute() throws Exception;

         public Object execute(Object parameters) throws Exception;

         ProcessBeanBase類提供了execute(Object)方法的一個實現,利用反射來產生子類提供的任何屬性。ProcessBeanBase使用了BeanUtils的方法。

14.3.4 執行ProcessBeans

         通常的策略是使用業務模型需要的屬性創建一個基類bean。這個基類bean被模型需要的任何一個業務過程擴展。爲產生bean的值,可以向execute(Object)傳遞所需的屬性的Map。缺省的實現會產生任何匹配的屬性,並觸發exectue方法來完成工作。

         Execute方法返回一個對象,通常是ProcessResult對象。ProcessResult對象用來向其他層傳輸業務操作的結果。ProcessResult可以包含消息、數據或者二者都包含,而且包含可以用來自動處理結果的方法。

         如果業務操作返回數據,數據通常包含在一個ResultList對象中。這是一個集合,具有很多幫助方法供表示層頁面方便地使用。ResultList被設計用來取代ResultSet,以便使用非連接的JavaBean。

14.3.5 訪問數據服務

         Artimus的ProcessBeans使用一個靜態類,Access,來從業務層連接資源層。這不是必需的,只是一個有用的規範。Access類代表着事實上的業務API。ProcessBeans代表着使用API的客戶端。

         Access類扮演着數據訪問對象的角色。如果需要使用多個實現,Access可以基於一個接口。Scaffold包提供了很多方便的工具來使用SQL語句和準備語句。Access類把合適的SQL語句和運行時bean傳遞的數據放在一起。

14.3.6 遵循一個典型的流程

n  ActionServlet產生一個ActionForm傳遞給Action的execute方法

n  Action創建、產生和執行適當的ProcessBean

n  如果發生錯誤,Action捕獲異常,將控制路由到錯誤或輸入頁面

n  如果操作成功,Action刷新ActionForm,把ResultList對象傳遞給請求的上下文

14.3.7 編寫一個業務活動的代碼

         Struts配置文件中ActionMapping中的parameter屬性,指定一個業務邏輯對象,Action會實例化這個對象。

14.3.8 把ProcessBeans用作持久層

         ProcessBeans和其他Scaffold對象形成一個持久層。

14.3.9 使用其他持久層

         Simpler,OJB,Castor,Osage

14.4 使用結果對象

         一旦取得了數據,還需要與表示層通信。可以使用標準的Vector和ArrayList,但一般使用特定的wrapper會更方便。

14.4.1 ResultList的方法

         就是一個wrapper的例子。ResultList類有幾個方法特別有用。

         int getSize()

         String getLegend():取得result list的一個描述。

         Iterator getIterator():取得result list的一個迭代子。

14.5 使用其他幫助Actions

         Struts開發者的通常的策略是爲幾個相關聯的操作使用一個Action。這樣有助於複用代碼和減少代碼中的類。Scaffold包中的幫助Actions實現了一株框架Action,可以被應用程序中幾乎所有的操作複用。

         幫助Action的策略是將一組業務對象與ActionMapping關聯。業務對象被實例化,產生值並調用。Action集中於錯誤處理和流程控制。

         幾個幫助Actions:

         BaseAction

         BaseHelperAction

         ProcessAction

14.6 使用Lucene

         數據庫的具有很多侷限性,特別是在搜索文本的時候:

         ANSI SQL文本搜索是區分大小寫的。

         SQL匹配符將參數當作單個字符串。

         SQL查詢只能通過一個字段的內容排序,匹配程度最高的不能被列在前面。

         大多數數據庫系統沒有對文本搜索做索引。效率可能不高。

         大多數數據庫系統沒有對布爾查詢做優化,使用布爾查詢的文本搜索可能會成爲系統的瓶頸。

         數據庫系統只能搜索存儲在表中的數據。

         Lucene解決了以上所有的問題。

14.6.1 searchProperties

         引入Lucene

         Lucene既是一個搜索引擎,又是一個構造搜索引擎的工具。Lucene有五個關鍵對象。

         Document:

一個邏輯構造體,可能是數據庫的一條記錄,一個網站的頁面或者是其他可以被重新取得的一條信息。

         Field:

                   Field是Document的一部分。每一個Field包含兩個部分:name和value。

         Index:

         Query:

         Hits:

         典型的工作流程:

n  通過增加Fields創建Documents

n  創建一個IndexWriter,並使用addDocument的方法增加Document

n  調用QueryParser.parse方法從一個字符串構造一個查詢

n  創建一個IndexSearcher,並將Query傳遞給它的search方法

n  將Hits生成一個list並返回給用戶

 

Artimus是如何使用Lucene的?

創建索引。

n  使用IndexWriter創建一個Index

n  創建一個Document對象(2)

n  獲取數據源

n  根據數據源向Document增加一個或多個Field

n  向Index增加Document對象(5)

n  對於每一個數據源重複2到5的操作

n  優化和關閉Index

14.7 使用內容聚合

策略很簡單:

n  可用的內容綜合在一個XML文件中

n  XML文件通過HTTP可用

其他站點可以:

n  獲取或緩衝這個文件

n  將這個聚合內容傳遞給它自己的訪問者

使用Struts Digester,創建和獲取聚合內容非常簡單。

14.7.1 Digesting RSS

         Struts使用Digester從Struts配置文件創建對象。

         一個RSS文件一個叫做channel的items的集合。每一個item具有幾個屬性,包含對這個item自己的鏈接,每一個屬性通常是站點的某個地方。Channel通常將關聯的items放在一起。

14.7.2 獲取和產生

         從一個既存的XML文件創建一個Channel對象非常簡單。只要傳遞一個path,剩下的事情交給RSSDigester就行了。

         創建自己的RSS文件也很容易。只要創建一個Channel對象,增加items,使用Writer產生結果就行了。

14.7.3 聚合RSS

14.8 在Struts中使用EJB

         EJB用來表示一個應用的Model層。當創建的應用會分佈在多個服務器上時,開發者通常會選擇EJB。很多開發者喜歡EJB因爲它對事務處理的透明性。

14.8.1 Session Façade

         EJB的session bean組件用來實現Façade接口。

14.8.2 數據傳輸對象

         ActionForm也是一種DTO。只要是在層與層之間傳輸的對象都可以教DTO。

14.8.3 實現模式

n  如果需要,重新創建對遠程接口的引用

n  優先使用無狀態的session EJBs,而不是有狀態的session EJBs

n  避免保持對無狀態的session EJBs的句柄

n  避免直接與實體交互

n  使用無狀態的façade來向Action返回DTO

第四部分 Struts使用實例

第十五章            Artimus:停車站

15.1 框架的框架

15.2 Scaffold—工具集的誕生

         如同Tiles和Validator,Scaffold是使用Struts創建Web應用的一個工具包。

15.3 關於Artimus

         Artimus是一個基於Web的新聞發佈應用。授權的用戶可以添加、刪除、編輯文章。任何訪問者可以在線查閱文章,可以使用各種搜索特性,包括通過作者、標題、時間段的全文檢索。

         Artimus可以將它的文章發佈成RSS Channel。

         Artimus是一個很好的使用Struts的例子,一些技術點:

n  應用程序的設置可以通過web.xml或其他屬性文件配置。

n  在Struts1.0版本中,一個幫助Servlet用來加載自定義的資源而不需要從ActionServlet繼承,而在Struts1.1中,使用PlugIn Action。

n  連接池適配器允許使用Struts連接池。連接池可以通過web.xml或PlugIn配置來改變。

n  SQL命令存儲在外部屬性文件中,不需重新編譯就可以修改。

n  業務層由一組ProcessBeans表示,使用經典的Command模式來分發。

n  使用標準的Action來分發ProcessBeans,減少了應用程序中自定義Action的使用。

n  應用程序很容易區域化。

n  Tiles框架可以用來佈局和組織顯示頁面。

n  Validator框架可以用來驗證輸入,服務器端和客戶端都可以。

n  Lucene搜索引擎可以用來提供全文檢索。

15.3.1 構建Artimus

15.4 部署描述子(web.xml)

         Artimus的web.xml除了包含Struts標準配置,還包含它自己的ArtimusServlet和Declarative Security配置。ArtimusServlet不是用來處理請求的運行時servlet,只是一個資源加載器,用來初始化我們的業務層的類。Declarative Security用來保護編輯命令,使未授權用戶不能訪問。

15.4.1 配置Artimus

         給Artimus servlet一個引用名稱,指定供容器加載的類。

15.4.2 應用程序屬性

       使用<default>指定一個應用程序使用的屬性文件的路徑,這個文件用來存儲系統路徑和其他一些不隨locale改變的設置。

         例如,Lucene需要在服務器上存儲一些文件,我們可以把路徑存儲在屬性文件中,需要改變的時候只要修改這個屬性文件,而無需重新編譯代碼。

15.4.3 連接適配器

         Artimus使用JDBC作爲缺省的存儲系統。

         使用<adaptor>和<adaptor.key>來配置連接適配器,以使用Struts的通用連接池。Struts在應用程序上下文中存儲一個對其連接池的引用。因爲這是一個通用的方法,Scaffold包提供了一個標準的ServletAdaptor。

15.4.4 啓動優先級

         <load-on-startup>:設置成1,讓容器先加載資源文件,因爲其他servlet可能也會使用加載的資源。

15.4.5 其他配置的設置

         其他的設置同Struts的標準設置。

15.4.6 安全的配置

         Artimus使用標準的Declarative Security模式。容器負責管理這種安全問題。

15.4.7 保護的URLs

         指定URL patterns。

15.4.8 授權用戶

         可以爲用戶分配多個角色,每個角色可以設定各自的資源。

15.4.9 授權策略

         <auth-method>指定授權策略。還有其他更安全的模式,但不是所有的瀏覽器都支持。

15.5 ArtimusServlet

         ArtimusServlet用來初始化一些應用程序的自定義的資源。使用自己的資源加載器的好處有:

n  可以提取大部分的子類來做大部分的工作

n  限制綁定到Struts的自定義代碼的數量

n  將代碼從可能發生在ActionServlet或PlugIn中的變化中保護起來

Artimus需要加載三個屬性文件和初始化兩個內部服務:

n  Artimus系統屬性文件

n  兩個SQL屬性文件

n  連接適配器

n  Lucene搜索引擎

資源加載器從標準的Scaffold包中的類繼承。

15.5.1 我們的子類

         ArtimusServlet從ConnectionServlet類繼承,一個標準的Scaffold類。ConnectionServlet自動地初始化連接適配器。

         ConnectionServlet從ResourceServlet繼承,ResourceServlet自動地加載缺省的資源文件。ResourceServlet也提供方法來加載其他屬性文件。我們將使用這個工具方法來加載SQL命令。

15.5.2 String tokens

         作爲一種編碼風格,所用字符串常量,都使用靜態的常量。

15.5.3 我們的擴展點

         ResourceServlet提供了initCustom方法作爲擴展點,子類可以添加自己的初始化代碼。ArtimusServlet重寫了initCustom方法來加載SQL命令屬性和設置Lucene索引文件的路徑。

         獲取SQL命令

         每一個SQL屬性文件都是使用ResourceServlet提供的loadProperties方法加載。這個方法在web.xml中檢查自定義的設置,如果沒有找到則使用提供的缺省值。

         爲使用loadProperties,我們需要傳遞:

n  初始化參數的名稱

n  如果沒有指定,則使用缺省值

n  可選地傳遞應用程序上下文的屬性名稱

如果傳遞了屬性名稱,loadProperties將在應用程序上下文中保存屬性文件的一個引用。

初始化Lucene索引路徑

15.6 應用程序和SQL屬性文件

         使用標準的name-value格式。

15.7 index.jsp

15.8 全局的Forwards

15.9 /find/Recent

         業務邏輯對象FindByLast類。

15.9.1 繼承Bean

         在大型應用中,每個包可能都需要自己的基類bean,由不同的開發組成員來管理。

         Bean類從ProcessBeanBase類繼承,這是一個輕量級的類,提供了兩個方便的屬性,和一個標準的入口方法來調用Bean。

         標準的入口方法,使得其他過程,如Struts的Action類以相同的方式調用每一個對象(控制反轉技術IOC)。Scaffold包定義了Executable接口來提供ProcessBean和其他Artimus Beans的入口方法。

15.9.2 super.execute

         通過execute方法進入我們的FindByLast類業務Bean。ProcessBeanBase的execute方法的缺省行爲是通過反射將parameters對象轉換成Map。

15.9.3 getArticles

         需要一個參數:要返回的文章的數目。

15.9.4 Access.findByLast和ResultList

         ResultList

15.9.5 ProcessResult

         ProcessResult接口定義一個傳輸對象,這個傳輸對象可以用來描述幾種可能的結果。ProcessResultBase實現了ProcessResult接口。

15.9.6 ProcessAction

         所有的查找Action都調用ProcessAction,ProcessAction對象又調用業務層的bean(在parameter中指定bean的類型)。

15.10 tiles.xml和Article.jsp

15.10.1 useAttribute

         Tiles使用自己的上下文。當Tiles的Definitions對一個值使用put時,其實是把值放在了Tiles的上下文環境中。<userAttribute>標籤使值在標準的上下文環境中可用,缺省的上下文環境是page範圍的。

15.10.2 baseStyle

         爲使容易地改變樣式表,將樣式表的路徑維護成ActionForward。Rewrite標籤從Struts配置文件返回樣式表的路徑。

15.10.3 title

         <bean:message>

15.10.4 Tiles

15.11 result.jsp

15.11.1 legend

15.11.2 isResult?

         如果結果數目爲0,則不打印表頭。

15.11.3 RESULT

         <html:link>

         <html:link>首先從全局的forward article獲取path屬性,即/do/view/Article。paramProperty和paramId屬性指定使用article查詢字符串參數的名稱,row.getArticle()作爲值。

         contributedDisplay

         對於字符串的顯示的格式的需求可能各種各樣。使用幫助方法。

15.12 Article Actions

15.13 view.jsp

15.13.1 headline

         樣式表在layout頁面定義。

15.13.2 content

         <bean:writer>的filter屬性設成false,允許向頁面輸出HTML。Filter的缺省值是true。

15.13.3 contributor

15.14 edit.jsp

15.14.1 Article的內容

15.14.2 contributed/contributor

15.14.3 Article ID

         添加和編輯使用同一個頁面,是通過存不存在ID來區別的。

15.14.4 Validation

         服務器端驗證

         客戶端驗證

15.15 /do/Menu

15.15.1 logon

         在使用/admin下的URI之前,容器會保證用戶已經登錄。

15.15.2 menu

15.15.3 控件

         Option list。

15.15.4 saveResult

         創建一個新的ProcessResult的list,並放在application範圍的上下文環境中。

15.15.5 結果

15.16 menu.jsp

15.16.1 /find/Hours

15.16.2 /menu/Find

15.16.3 /find/Last

15.16.4 /menu/Contributor

15.16.5 /menu/Manager

第十六章            移植到Struts1.1

16.1 下一站—Struts1.1

         在Struts1.1中,有一些包從Struts包中提到Jakarta Commons包中。使用這些包的類需要引入這些包:

n  BeanUtils包,代替BeanUtils包,ConvertUtils包,PropertyUtils包。

n  Collections包,代替ArrayStack,FastArrayList,FastHashMap,FastTreeMap

n  Digester包,代替原來的Digester包

如果使用了Struts1.0的Tiles和Validator,還需要:

n  改變對Validator包的引用

n  改變對Tiles的引用

n  將對Tiles和Validator的引用從web.xml中移除

n  在Struts配置文件中添加集成版本的Tiles和Validator的引用

16.1.1 Struts1.1的新特性

n  多個消息資源Message Resources

n  模塊化應用程序

n  Dynamic ActionForms

n  Actions的Roles屬性

n  Messages和Errors的分離的隊列

n  LookupDispatchAction

n  SwitchAction

n  聲明式的異常處理

n  RequestProcessor

n  PlugIn Actions

n  通用的日誌接口

n  LabelValueBean

n  嵌套的標籤庫

n  新的Empty/notEmpty標籤

n  新的frame標籤

n  新的OptionsCollections標籤

n  新的radio標籤的idName屬性

n  新的indexed標籤屬性

n  新的JavascriptValidator標籤

n  Tiles框架

n  Struts Validator

16.1.2 我們可以使用的特性

         DynaActionForm和基於Action的安全。

16.2 基線變更

16.2.1 Struts1.1中的Tiles

         Tiles通過監視引用Definitions的ActionForwards。

16.2.2 Struts1.1中的Validator

         可能需要調整一些頁面。

16.2.3 Struts1.1中的ReloadAction

         刪除了ReloadAction。

16.2.4 其他一些對web.xml和struts-config.xml的基線變更

16.2.5 message.jsp(1.1)

         <validator:messagesExist>變爲<logic:messagesExist>。

16.2.6 form.jsp(1.1)

16.2.7 MenuCreate(1.1)

16.3 Discretionay Changes

n  配置DynaActionForm

n  添加roles,實現基於Actions的安全

n  添加新的配置元素來加載缺省的消息資源

第十七章            Velocity:替換JSPs

17.1 移向Velocity模板

         變化是計算機科學的核心。

17.2 變化成就框架

         應用程序的一大部分成本花費在維護上。Struts通過封裝最有可能變化的細節來使維護變得容易。這些細節中最主要的一部分是被Action引用的頁面。

         Velocity特別對於那些不是Java工程師或JSP狂熱者的頁面設計師很重要。

         對於Struts應用,最主要的變化是在Struts配置文件中。Struts配置文件被設計出來,是爲了集中實現細節,例如表示層頁面或模板的名稱。如果web應用的所有超鏈接都使用ActionForwards,那麼只需要改變Struts配置文件就可以改變鏈接引用的頁面。

17.3 我們爲什麼需要Velocity?

         既然有了JSP,爲什麼需要Velocity?

17.3.1 Velocity是輕量的、快速的、多功能的

         Velocity模塊需要更少的代碼,產生的更快。Velocity模板可以用在任何需要在運行時創建定製化輸出Java應用程序中。Velocity可以用來從模板產生SQL,PostScript,e-mail,或XML。

17.3.2 Velocity能與其他工具很好地協作

         Velocity代碼可以在可視化HTML編輯器中很好地顯示,因此頁面設計者通常會發現Velocity模板比JSP頁面更容易使用。

17.3.3 Velocity簡單而且強大

         Velocity模板語言(VTL)。

n  #set:建立一個引用的值

n  #if/#elseif/#else:提供條件輸出

n  #foreach:對列表循環處理

n  #include:產生不被Velocity解析的本地文件

n  #parse:產生一個被Velocity解析的本地模板

n  #stop:停止模板引擎

n  #macro:定義一個VelociMacro(VM),VTL模板的一個重複的片段

n  ##:指定一個單行的註釋

n  #*…*#:指定一個多行的註釋

n  ${variable}:提供一個變量的引用

n  ${purchase.Total}:引用一個屬性,如purchase.Total或purchase.getTotal()

n  ${purchase.setTitle(“value”):引用一個方法

17.4 在web應用中使用Velocity

         在Velocity中,在實際運行時使用模板來創建響應。在web環境下,Velocity servlet返回結果作爲HTTP請求的響應。

         在處理模板的時候,Velocity Template Engine被給予一個運行時環境,包含了變量信息。Velocity提供了自己的上下文對象,所以同樣的模板引擎可以用在web環境中,也可以用在一般的Java應用中。

         在web應用中,Velocity可以把標準的servlet上下文環境用作自己的上下文。當Velocity採用上下文環境時,它使用與JSP標籤相同的策略。

         當引擎產生一個模板時,它查找Velocity語句和引用。由出現在行首的#和關鍵字標識。引用是對上下文中的變量的引用。引用又一個$和緊跟的一個名稱來標識。任何一個Java對象都可以放在上下文中作爲一個引用。引用可以訪問Java類的任何public方法。

17.4.1 將Velocity與servlet資源一起使用

         Web應用中的很多組件間的通信都與都與servlet提供的四個標準的資源有關:application上下文,session,request,respons。Applicatin上下文讓組件共享數據和服務。Session對象爲每一個用戶提供數據和服務。Response與request一起工作來完成HTTP請求—響應週期。

         Velocity提供了一個標準的VelocityViewServlet使Velocity與應用程序中的任何servlet的繼承更加容易。

         例子:對於使用<request>標籤檢查用戶的安全角色,可以這樣書寫:

         <request:isUserInRole role=”contributor”>

         <%--…%>

         </request:isUserInRole>

         同樣的檢查使用Velocity可以這樣做:

         #if $request.isUserInRole(“contributor”)

         #...

         #endif

17.4.2 在Velocity中使用上下文屬性

         <P>Username: ${session.getAttribute("username")}</P>

17.4.3 Velocity如何與Struts工作

         與Struts綁定的JSP標籤使用一個叫做RequestUtils的類來訪問Struts配置對象。

         實際上,VelocityStruts工具和它的查看工具可以做與RequestUtils相同的事情。

17.4.4 VelocityStruts工具

         VelocityViewServlet與Struts的ActionServlet一起加載到應用程序中。Velocity servlet被配置來匹配一些URL模式,通常是*.vm。一旦Velocity servlet被加載,我們可以向轉發到JSP文件一樣轉發到VM文件。

17.4.5 Struts View工具

         $msg:MessageTool,提供對Struts消息資源的訪問

         $errors:ErrorsTool,提供檢查和輸入Struts錯誤消息

         $link:LinkTool,提供方法與URI工作

         $form,FormTool,提供方法與Struts應用程序中的form和form bean工作。

17.5 我們的Logon模板

17.6 設置VelocityViewServlet

17.6.1 安裝VelocityViewServlet

         Velocity-tools-view.jar

         Velocity-tools-library.jar

         Velocity-tools-struts.jar

         Dom4j.jar

         Jakarta-commons-collections.jar

         Toolbox.xml

17.6.2 部署Velocity Servlet

         如同配置其他servlet一樣,在web.xml中配置。

         Toolbox參數

         用來指定工具配置文件。

         Properties屬性

         Velocity提供了很多配置選項,放在了Properties文件中。

17.6.3 toolbox配置文件

17.7      設置struts-config文件

A設計模式

         Struts本身實現了很多經典的模式,首先就是MVC模式。

A.1 設計模式的簡要歷史

         可以說Struts是“站在巨人的肩膀上”。這裏的巨人叫做設計模式。

A.1.1 四人幫

         23個有用的模式。

A.1.2 J2EE Blueprints

         J2EE Blueprints是一組指南、設計模式和示例代碼,都是用來體現J2EE最佳實踐的。

A.1.3 核心J2EE模式

         建立在四人幫的《設計模式》的基礎上。

A.2 爲什麼模式重要?

         經驗證的解決方案、便於交流、優缺點都列出來了。。。

A.3 模式不能做什麼?

         模式幫助我們確定做什麼和怎麼做,而不能告訴我們爲什麼做和什麼時候做。

A.4 Struts-A who’s who of design patterns

         Struts是一個利用模式的很好的例子。

         Struts實現的一些核心J2EE模式:

n  Service to Worker

n  Command,Command and Controller,Front Controller,Singleton,Service Locator

n  Dispatcher,Navigator

n  View Helper,Session Façade,Singleton

n  Transfer Objects,Value Object Assembler

n  View Helper

n  Composite View,Value ObjectAssembler

n  Synchronizer Token

n  Decorator

A.4.1 Service to Worker模式

         這是一個宏觀的模式,使用其他兩個模式。

         Front Controller模式

         ActionServlet提供了一個請求處理的中心訪問點,這叫做Front Controller模式。

         Command/Command and Controller模式

         ActionServlet調用Action類已知的方法,並傳遞請求的一些細節。這叫做Command and Controller模式,是基於Command模式的。

Service Locator模式

Struts開發者可以切換JDBC驅動,連接池等等,只需要改變註冊的Datasource的邏輯名稱。

View Helper模式

使用JavaBean來將業務數據傳遞給view組件,這種模式叫做View Helper模式。

A.4.2 Singleton模式

         Action使用單例模式,但把書寫線程安全的Actions的責任交給了開發者。

A.4.3 Session Façade模式

         消息資源組件使用此模式,隱藏了選擇用戶locale的複雜性,只需要通過key來獲取message。

A.4.4 Value Object/Value Object Assembler模式

         把很多值放在一個對象中傳輸。

A.4.5 Composite View模式

         模板標籤。

A.4.6 Synchronizer Token模式

         防止重複提交。

A.4.7 Decorator模式

         ActionMapping類用來擴展Action對象而不是Action類。

B Struts-config API

B.1 <struts-config>

         <struts-config>是配置文件的根節點,它包含了所有其他配置設置的嵌套元素。其他元素有:

n  set-property:指定一個方法名和另外的JavaBean的配置屬性的初始值。

n  data-sources:指定一組data-source對象。

n  global-exceptions:描述一組可能被Actions對象拋出的異常。

n  exception:爲一個異常類型註冊一個ExceptionHandler。

n  form-beans:爲應用程序模塊描述一組form bean描述子。

n  form-bean:指定一個可以被Action引用的ActionForm的子類。

n  form-property:指定一個JavaBean的屬性,用來配置DynaActionForm及其子類。

n  global-forwards:描述一組ActionForwards對象,可以作爲所有Action的返回值。

n  forward:描述一個ActionForward對象,可以作爲一個Action的返回值。

n  action-mappings:描述一組ActionMappings,可以用來處理匹配我們的ActionServlet在容器中註冊的URL模式的請求。

n  action:描述一個ActionMapping對象,用來處理特定的模塊相關的URI的請求。

n  controller:描述ControllerConfig bean,用來封裝應用程序模塊的運行時配置。

n  message-resources:描述一個MessageResource對象。

n  plug-in:指定一個plugIn的類名,用來接受應用程序啓動和關閉事件的通知。 

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