0 序... 2
0.1猜想... 2
0.2 HTTP,HTML,User Agents. 2
0.3 HTTP 請求/響應(yīng)周期... 2
0.4 Java語言和應(yīng)用框架... 2
0.5 JavaBeans. 2
0.6屬性文件和資源綁定... 3
0.7 JavaServlet 3
1介紹... 5
1.1Struts的歷史... 5
1.2 MVC模式... 6
1.3 Struts控制流程... 7
2 創(chuàng)建模型組件... 8
2.1概述... 8
2.2 JavaBean和作用域... 8
2.3 ActionForm Bean. 9
2.4系統(tǒng)狀態(tài)Bean. 9
2.5商業(yè)邏輯Bean. 9
3 創(chuàng)建視圖組件... 9
3.1 概述... 9
3.2 國際化信息... 9
3.3Forms 和 FormBeans的交互... 11
3.4 其他表示層技術(shù)... 13
4 創(chuàng)建控制(Controller)組件... 15
4.1 概述... 15
4.2 ActionServlet 15
4.3 ActionForm類... 16
4.4 Action類... 19
4.5 異常處理器... 20
4.6 插件類... 20
4.7 ActionMapping的實現(xiàn)... 20
4.8 編寫Action Mappings. 21
4.9 在頁面中使用ActionMapping. 22
4.10 在ActionMapping中使用通配符... 22
4.11 公共的Log 接口... 23
5. 配置應(yīng)用... 23
5.1 概述... 23
5.2 Struts配置文件... 23
5.3 為應(yīng)用配置模塊... 25
5.4 WEB應(yīng)用部署描述符... 25
0 序
0.1猜想
本手冊適合于有創(chuàng)建Java Web 應(yīng)用經(jīng)驗的Web 開發(fā)人員.在開始學習Struts之前你應(yīng)該了解如下的技術(shù):
1. HTTP,HTML,User Agents
2. HTTP 請求/響應(yīng)生命周期
3. Java語言和應(yīng)用框架
4. JavaBeans
5. 屬性文件和資源綁定
6. Java Servlets
7. Java Server Pages ,JSP Tag Librariy
8. XML
0.2 HTTP,HTML,User Agents
WWW是基于超文本傳輸協(xié)議和超文本標識語言建立的.
用戶代理,比如瀏覽器,他們使用HTTP去請求一個文檔然后格式化顯示.
0.3 HTTP 請求/響應(yīng)周期
對于Web開發(fā)者來說,理解HTTP的請求和響應(yīng)周期是很重要的.你要使用HTTP發(fā)送一個請求,然后服務(wù)器給你一個響應(yīng).當你創(chuàng)建WEB應(yīng)用時,你需要返回一個響應(yīng)對象來回應(yīng)請求.
0.4 Java語言和應(yīng)用框架
Struts是用JAVA編寫的.JAVA是面向?qū)ο蟮恼Z言,而Struts充分利用了面向?qū)ο蟮募夹g(shù).除此而外JAVA支持線程.如果你很好的掌握了JAVA,特別是面向?qū)ο缶幊毯途€程,這將會有益于最有效的使用Struts和這個手冊.
0.5 JavaBeans
象大多數(shù)JAVA應(yīng)用一樣,大多數(shù)Struts對象都是JavaBean.遵循JavaBean設(shè)計模式使得Struts更容易被開發(fā)者和JAVA開發(fā)工具使用.盡管JavaBean的最初是用來開發(fā)可視元素的,但它對開發(fā)可重用組件也非常有益.
0.5.1反射和內(nèi)省
反射是決定什么樣的函數(shù)或域存在某對象中的方法.內(nèi)省是反射的特殊形式.
使用內(nèi)省就可以知道哪些方法將會被其他對象使用(如getter,setter)
Struts框架使用內(nèi)省來轉(zhuǎn)換HTTP參數(shù)到JAVABEAN的屬性中和把JAVABEAN中的屬性數(shù)據(jù)組裝到HTML的域.
0.5.2 MAP
JAVABEAN把數(shù)據(jù)存在屬性中.JAVABEAN雖然是靈活而功能強的對象,但它并不是編程者存儲數(shù)據(jù)的唯一對象.另一個熟為人知的對象是java.util.Map.Map它是一個名字/值對的數(shù)據(jù)集合,它經(jīng)常用來存儲動態(tài)數(shù)據(jù).
0.5.3 DynaBeans
DynaBeans集成了JAVABEAN 的擴展性和MAP的靈活性.編寫JAVABEAN要創(chuàng)建一個新類,并且要為每個屬性編寫方法.DynaBeans則將屬性放在XML中配置.
在Struts應(yīng)用中,你可以使用DynaBeans來描述你的HTML Form,這個策略可以避免編寫普通的JAVABEAN來存儲很簡單的屬性.
0.6屬性文件和資源綁定
JAVA應(yīng)用包括WEB應(yīng)用的配置經(jīng)常使用屬性文件來完成. Struts的消息資源都是通過資源綁定和屬性文件實現(xiàn)的.
JAVA資源綁定使用一個或多個屬性文件來實現(xiàn)應(yīng)用的國際化.
0.7 JavaServlet
由于JAVA是面向?qū)ο蟮恼Z言,因此JAVA平臺已經(jīng)將HTTP轉(zhuǎn)換成對象的形式.這將會使JAVA 程序員關(guān)注于應(yīng)用本身而不是HTTP.
HTTP提供了一個標準的機制來擴展服務(wù)器的功能,我們稱之為CGI. 服務(wù)器將請求發(fā)送到CGI程序,CGI程序則返回一個響應(yīng).同樣的任何JAVA服務(wù)器則會接收請求,然后轉(zhuǎn)發(fā)到Servlet.
Servelt 是javax.servlet.http.HttpServlet的子類,每個Servlet必須完成四個方法:
* public void init(ServletConfig config)
* public void doGet(HttpServletRequest request, HttpServletResponse response)
* public void doPost(HttpServletRequest request, HttpServletResponse response)
* public void destroy()
Struts提供了一個可用的Servlet--org.apache.struts.action.ActionServlet.
作為一個Struts開發(fā)者,你只需要編寫對象供ActionServlet調(diào)用就行了.但是,理解Servlet并熟悉他在JAVA WEB應(yīng)用中扮演的角色那是最好不過了.
0.7.1 Servlets 和多線程
為了提高性能,Servlet設(shè)計程多線程.每個Servlet僅創(chuàng)建一個實例,每一個請求都傳遞到同一個對象.這將有利于Servlet容器充分的利用資源.因此doGet,doPos在編程時必須保證他是線程安全的.
0.7.2 Servlet Context
ServletContext(javax.servlet.ServletContext)定義了Web 應(yīng)用中Servlet的視圖.在Servlet中通過getServletConfig()可以訪問得到,在JSP中則通過隱式對象application得到.ServletContext提供了幾個對于創(chuàng)建Struts應(yīng)用來說非常有用的幾個方法:
1.訪問WEB應(yīng)用資源 Servlet通過getResource(),getResourceAsStream()可以訪問WEB應(yīng)用中的靜態(tài)資源文件.
2.Servlet Context屬性 Servlet上下文可以存儲JAVA對象到屬性中.這些屬性對整個WEB應(yīng)用都可見.
0.7.3 Servlet請求
Servlet請求就是javax.servlet.http.HttpServletRequest,通過它可以訪問HTTP請求的所有信息:
1. Cookies 通過getCookies()可以得到當前請求的所有cookie
2. HTTP頭 HTTP請求的頭可以通過對應(yīng)的名字來訪問.你當然可以通過枚舉來列出所有的頭.
3. 參數(shù) 你可以通過參數(shù)來訪問HTTP請求的URL的參數(shù)或表單中的內(nèi)容.
4. 請求特性 HTTP請求表單的提交方式(GET/POST),用的是什么協(xié)議(HTTP/HTTPS)
5. 請求URI信息 通過getRequestURI()可以得到最初的請求URI,除此之外,我們還可以得到contextPath,servletPath,pathInfo
6. 用戶信息 如果你正使用容器來進行安全管理,你可以得到一個Principal對象來代表當前用戶,并確認該用戶是否擁有某叫角色的權(quán)限.
Servlet請求擁有請求級別的屬性,與前面提到的應(yīng)用級別屬性類似.請求級別的屬性經(jīng)常用來傳遞狀態(tài)信息到可視化組件(如JSP).
Servlet容器保證被Servlet處理的請求處于單線程內(nèi).因此你不必擔心在訪問request對象的屬性時會有多線程的問題.
0.7.4 Servlet響應(yīng)
Servlet的功能就是接收請求,然后生成相應(yīng)的響應(yīng). 這是通過調(diào)用javax.servlet.http.HttpServletResponse的方法實現(xiàn)的.
1.設(shè)置頭 你可以設(shè)置包含在響應(yīng)中的頭.最重要的頭就是Content-Type,它用來告訴客戶端內(nèi)容的格式,比如:text/html代表html,text/xml代表XML
2.設(shè)置Cookies 你可以加入cookie到當前的響應(yīng)中
3.發(fā)送錯誤響應(yīng) 你可以使用sendError()發(fā)送一個HTTP錯誤編號
4.重定向到其他資源 你可以使用sendRedirect()定向到另外一個URL
使用Response API的一個最重要的原則就是:操作Header,Cookie的任何方法必須在第一次輸出緩沖區(qū)滿且發(fā)送到客戶端前調(diào)用.
0.7.5過濾
如果你的Servlet容器是基于Servlet規(guī)范2.3或更高,那么你就可以使用javax.servlet.Filter來對請求和響應(yīng)作些處理.許多filter聚合在一起,每一個filter都有機會來對請求和響應(yīng)做處理.
Struts1.0,1.1,1.2只需要Servlet規(guī)范2.2,因此這些版本的Struts并不支持filter.
Struts從1.3開始就需要Servlet規(guī)范2.3的容器了.
0.7.6 Session
HTTP的一個關(guān)鍵特性就是無狀態(tài),因此我們不知道某個請求是否是來自同一用戶的請求,這將會使跨請求的會話變得很艱難.
為了解決這個問題,Servelet實現(xiàn)了一個javax.servlet.http.HttpSession.Servlet容器將采用Cookie或URL Rewriting來保證接鄰近的請求包含session id來標識該請求是同一個session.因此保存在session中的屬性可以被多個請求共享.
為了不浪費資源,Session有一個可配置的超時時間設(shè)置.如果兩個請求間的時間差超過了超時時間間隔,那么session中的數(shù)據(jù)會失效.你可以定義一個默認的超時時間在WEB應(yīng)用部署描述文件中,或者你也可以通過setMaxInactiveInterval()動態(tài)改變它.
與request不一樣的是,你必須關(guān)心session的屬性是線程安全的,(bean提供的方法,并不是session的getAttribute和setAttribute)
比較重要的一點需要考慮的是:因為session的屬性是占用內(nèi)存的時間較長,因此在用戶量大時,要考慮session的屬性占用內(nèi)存的大小.
0.7.7分發(fā)請求
1介紹
1.1Struts的歷史
Servlet剛出道時,很多Java開發(fā)者意識到它將會比CGI更快,更有效,更容易移植.
但是通過println()將HTML輸出到客戶端是很煩人和容易出錯的.于是人們在JSP中找到了答案,通過將JAVA代碼與HTML混合在一起.
JAVA WEB應(yīng)用開發(fā)隨之也變得以JSP為中心點.這并不是壞事.關(guān)鍵的是它沒有給WEB應(yīng)用的流程控制及其它問題提供更多的解決方法.
許多聰明的開發(fā)者意識到可以將Servlet,JSP同時部署到WEB應(yīng)用中.Servlet來做控制流程,JSP來生成HTML頁面.一個新的名詞Model 2 由此而生.
Model 2 對于SUN來說并不是新奇的事物.許多人指出Model 2遵循從Smalltalk MVC框架抽象出來的MVC模式.從而人們開始把Model 2 與MVC關(guān)聯(lián)到一起.
1.2 MVC模式
在MVC模式中,流程由控制器(Controller)管理.控制器將請求委派到相應(yīng)的處理器,處理器與Model連在一起,每個處理器在請求與Model之間充當一個適配的角色.Model封裝了商業(yè)邏輯或狀態(tài).然后控制流程將會轉(zhuǎn)到View. 轉(zhuǎn)向動作可以由存儲在數(shù)據(jù)庫或文件中的轉(zhuǎn)向定義來決定.這會讓View和Model之間的關(guān)系松散,從而有利于應(yīng)用的創(chuàng)建和維護.
1.2.1 Model(系統(tǒng)狀態(tài)和商業(yè)邏輯JavaBean)
基于MVC的系統(tǒng)可以的Model可分為兩部分:一個是系統(tǒng)的狀態(tài),另一個是改變這些狀態(tài)的行為.
大多數(shù)系統(tǒng)將系統(tǒng)狀態(tài)存儲在JAVABEAN中.根據(jù)系統(tǒng)復(fù)雜度的不同,有些Beans是自包含的(也就是BEAN本身知道如何持久化數(shù)據(jù)),有些是通過其它方式取得數(shù)據(jù)(數(shù)據(jù)庫,搜索引擎,EJB,LDAP).
在大型系統(tǒng)中JAVABEAN可能有很多方法來維護狀態(tài)信息.
在小型系統(tǒng)中,這些JAVABEAN的方法極有可能放到Struts框架的Action類中.如果商業(yè)邏輯很簡單或者它不會在其它地方重復(fù)調(diào)用,這是可以的.
Struts提供了許多靈活的方式來訪問Model,但我們強烈建議你將商業(yè)邏輯和Action類分離開來.
1.2.2 視圖(View)-JSP和可視組件
Struts應(yīng)用的視圖部分經(jīng)常是基于JSP的.JSP可以包含HTML,XML,及標簽.
Struts擁有一個標簽庫可以讓你創(chuàng)建國際化的用戶界面以及很好的與ActionForm beans集成在一起. ActionForm 捕獲,校驗應(yīng)用的輸入數(shù)據(jù).
1.2.3控制器-ActionServlet,ActionMapping
控制器負責接受來自客戶端的請求,并且決定將執(zhí)行哪個業(yè)務(wù)邏輯功能,然后再委托相應(yīng)的View來顯示用戶界面.
在Struts中,主要的控制器組件就是ActionServlet,它有一組ActionMapping,每一個ActionMapping會有某個請求URL的路徑和該URL對應(yīng)的Action 類.每一個Action都是org.apache.struts.action.Action的子類.Action去調(diào)用業(yè)務(wù)邏輯類,最終將控制權(quán)交給View組件.
1.3 Struts控制流程
Struts用幾個組件組成了MVC框架的控制層.它們由Controller servlet,開發(fā)者自定義的請求處理器(handler)和其它一些輔助類構(gòu)成.
Struts的自定義標簽庫為View層提供直接的支持.有些標簽可以訪問Control層的對象,有些則是為了方便開發(fā)應(yīng)用而寫的.其他的標簽庫如JSTL也可以與Struts一起使用.
Model層對不同的項目來說有很多不同.Struts讓model很容易被應(yīng)用的后臺邏輯所使用.
讓我們來看看Controller,View,Model是如何融合在一起的.
當初始化時,Controller解釋struts-config.xml并且使用它部署一些控制層的對象,這些對象構(gòu)成了Struts的基礎(chǔ).這個基礎(chǔ)當然少不了ActionMapping[org.apache.struts.action.ActionMappings].
當Struts要將請求傳遞到框架的其他組件時它就得參考ActionMapping,請求將會轉(zhuǎn)移到一個JSP或者Action--org.apache.struts.action.Action.通常,一個請求先派發(fā)到Action,然后再到JSP.
一個ActionMapping通常包含如下的屬性:
1. 請求路徑(或者URI)
2. 響應(yīng)請求的對象(Action 子類)
3. 其它所需要的屬性
Action對象可以處理請求和響應(yīng),或者將控制流轉(zhuǎn)向到其它地方.例如,如果登陸成功,將轉(zhuǎn)向到主頁面.
Action對象可以訪問應(yīng)用的Controller servlet,當控制流發(fā)生改變時,他可以將JAVABEAN放在合適的上下文中供多個Servlet共享.
例如,一個Action對象創(chuàng)建了一個購物車Bean,并且往購物車中加入所夠物品,然后把這個BEAN放在session中,當轉(zhuǎn)向到其他URL時,就可以用到先前創(chuàng)建的購物車.
在Struts應(yīng)用中,大多數(shù)的商業(yè)邏輯都放在JAVABEAN中,Action調(diào)用JAVABEAN的方法而不需要知道它是如何實現(xiàn)的.這樣一來就封裝了商業(yè)邏輯,而Action本身將集中到錯誤處理和轉(zhuǎn)向(Forward)的處理上.
JAVABEAN也可以用來管理輸入表單,設(shè)計WEB應(yīng)用的一個關(guān)鍵問題是如何保持和校驗在兩個請求之間的用戶所輸入的數(shù)據(jù).有了Struts,你就可以用org.apache.struts.action.ActionForm來存儲和校驗輸入表單.ActionForm被自動保存在合適的上下文中,因此它可以被其他的對象共享,如Action對象,JSP.
FormBean可以被JSP用來收集用戶數(shù)據(jù),也可以由Action對象來校驗用戶所輸入的數(shù)據(jù),還可由JSP把數(shù)據(jù)組裝到HTML的輸入域中.Struts擁有共享的拋出錯誤,顯示錯誤的機制.
另外一個Struts的培植元素就是ActionFormBeans --org.apache.struts.action.ActionFormBeans,它是一個描述性對象的集合,主要用于運行時動態(tài)創(chuàng)建ActionForm的實例.當一個URL映射需要ActionForm,Servlet就會通過名字去查找form-bean的描述對象,從而用它去創(chuàng)建ActionForm的實例.
下面是請求需要ActionForm時的事件序列:
1. Controller servlet檢索或者創(chuàng)建ActionForm
2. Controller servlet 將bean傳遞到ActionObject
3. 如果請求提交了一個輸入頁面,Action 對象可以檢查數(shù)據(jù).
4. 如果請求將要創(chuàng)建一個輸入界面, Action 對象將會組裝數(shù)據(jù)到任何輸入頁面中.
2 創(chuàng)建模型組件
2.1概述
許多創(chuàng)建WEB應(yīng)用的文檔都關(guān)注于View,然而我們應(yīng)該在Model的角度清晰定義需求的處理邏輯或過程.總之,Model的開發(fā)者將會創(chuàng)建JAVABEAN來實現(xiàn)功能需求.一個應(yīng)用的JAVABEAN需要什么樣的功能完全取決于需求,但它可以分為如下三類,在介紹他們之前,讓我們先看一下JAVABEAN的作用域
2.2 JavaBean和作用域
在WEB應(yīng)用中,JAVABEAN存儲許多不同的屬性集合中。每一個不同的屬性集合都有不同的生命周期規(guī)則。該規(guī)則定義了生命周期和可見性我們稱之為作用域(Scope),JSP定義的作用域如下:
1. page Bean在當前請求的單個JSP頁面可見(相當于Servlet的service方法中的局部變量)
2. Request Bean不僅在單個頁面可見,也可以在被頁面包含(include)的頁面或servlet中可見,或者轉(zhuǎn)向(Forward)的頁面可見。
3. Session Bean在特殊用戶session的所有JSP或Servlet中可見。
4. Application Bean在WEB 應(yīng)用中的所有JSP,或Servelt中可見。
必須記住的是JSP和Servlet在同一個WEB應(yīng)用中共享同一組Bean。例如一個Bean在Servlet中存在request的屬性中:
MyCart mycart = new MyCart(...);
request.setAttribute("cart", mycart);
Mycart在該Servlet轉(zhuǎn)向的JSP頁面中馬上可見。你可以在JSP中如下聲明它:
<jsp:useBean id="cart" scope="request"
class="com.mycompany.MyApp.MyCart"/>
2.3 ActionForm Bean
注意:ActionForm Bean的屬性經(jīng)常會對應(yīng)Model中Bean的屬性。Form bean應(yīng)該被看作是Controller的組件,同樣的,它能在Model和View兩層之間傳遞數(shù)據(jù)。
Struts假定你已經(jīng)為應(yīng)用的Form定義了ActionForm.ActionForm也通常成為form bean(表單bean)。一個bean可以服務(wù)于一個form,也可一服務(wù)于多個form或者整個應(yīng)用,這完全取決于你在設(shè)計form bean時的粒度。
如果你定義了ActionForm Bean在Struts的配置文件中,那么Struts框架會在執(zhí)行Action對象的方法之前為你自動執(zhí)行如下服務(wù):
1.檢查Bean是不是在適當?shù)淖饔糜?BR>2.如果Bean不存在,則創(chuàng)建一個實例,并且加入到適當?shù)淖饔糜蛏舷挛闹小?BR>3.如果請求的參數(shù)的名字與Bean中的屬性名字一致,對應(yīng)的setter方法就會被調(diào)用。
4.填滿數(shù)據(jù)的ActionForm Bean將會傳到org.apache.struts.Action的excute方法,因而系統(tǒng)狀態(tài)Bean和商業(yè)邏輯Bean就會有數(shù)據(jù)可用。
2.4系統(tǒng)狀態(tài)Bean
一個系統(tǒng)的狀態(tài)實際上是由許多JAVABEAN組成的。例如一個購物車系統(tǒng)對于用戶有個購物車的Bean,它里面有用戶當前購買的商品。系統(tǒng)里還有Bean來保存用戶的信息
2.5商業(yè)邏輯Bean
你需要封裝你的商業(yè)邏輯在JAVABEAN的方法中。這些方法可能放在系統(tǒng)狀態(tài)Bean中,但盡可能用一個單獨類來實現(xiàn)。如果是用單獨的類來實現(xiàn),你可能需要將系統(tǒng)狀態(tài)Bean 作為參數(shù)傳到商業(yè)邏輯Bean的方法中。
3 創(chuàng)建視圖組件
3.1 概述
這章將集中在Sruts的視圖部分。很多應(yīng)用依賴于JSP來創(chuàng)建展現(xiàn)層。Struts包含了支持國際化應(yīng)用的標簽,也有提供輸入表單交互的標簽。
3.2 國際化信息
多年以前,應(yīng)用開發(fā)者只需要支持自己國家的公民來使用軟件,他們可能使用一種語言或一種度量衡標準。隨著WEB應(yīng)用在全世界快速增長,應(yīng)用的國界也逐漸消失。因此應(yīng)用需要國際化和本地化。
Struts在JAVA平臺的基礎(chǔ)上來支持國際化和本地化。回顧一下我們熟悉的概念:
1. Locale - JAVA中支持國際化的最基本的類,它代表一個國家和語言,同時也假定了數(shù)字或時間的格式。
2.ResourceBundle - JAVA中工具類用來支持不同國家的信息。
3.PropertyResourceBundle - ResourceBundle的一個實現(xiàn),它允許你使用”name=value”的格式來初始化屬性文件。這對于準備WEB應(yīng)用的信息是非常方便的,因為這些信息都是文本。
4.MessageFormat - java.text.MessageFormat允許你在運行時用參數(shù)替換信息字符串中的部分信息。當某些信息在運行時將會顯示不同的順序或不同的語言時,MessageFormat將會非常有用。占位符{0}將被第一個參數(shù)代替,{1}將被第二個參數(shù)代替,依此類推。
5.MessageResource - org.apache.struts.util.MessageResources類把所有的資源綁定當作一個數(shù)據(jù)庫來看待,允許你請求不同的Locale的信息字符串(通常與當前用戶相關(guān)),而不是服務(wù)器上的Locale。
必須注意的是:Struts框架支持國際化僅僅限于展現(xiàn)給用戶的文本和圖片,支持本地化的輸入方法(例如使用何種語言)則由客戶端的設(shè)備(通常是瀏覽器)實現(xiàn)。
讓我們來了解一下將屬性文件綁定到WEB應(yīng)用的步驟,
假如你的代碼在com.mycompany.mypackage,為了實現(xiàn)資源綁定,你需要創(chuàng)建如下文件:
1.MyApplication.properties ? 默認語言的所有信息,如果默認語言是英語,在你的屬性文件中可能有如下入口prompt.hello=Hello
2.MyApplication_xx.properties - ISO語言代碼所對應(yīng)語言的所有信息,如果語言是法語,屬性文件中可能有如下入口prompt.hello=Bonjour
當你在WEB應(yīng)用的部署描述文件中定義Controller Servlet時,你可能需要把應(yīng)用的資源綁定名稱作為初始化參數(shù)傳進去。
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>application</param-name>
<param-value>
com.mycompany.mypackage.MyResources
</param-value>
</init-param>
<!-- ... -->
</servlet>
最重要的是要保證資源綁定能在你的應(yīng)用的CLASSPATH找得到。另外一個方法就是把MyResources.properties放在classes目錄,然后用MyResoureces來引用就行了。
3.3Forms 和 FormBeans的交互
很多WEB開發(fā)者使用HTML本身的功能來實現(xiàn)表單,比如Input。用戶期望交互應(yīng)用能具備某些必備的功能,比如錯誤處理(當出現(xiàn)錯誤時,只需要修改導致錯誤出現(xiàn)的地方,而不要重新輸入頁面或表單中的信息)。
用標準的HTML和JSP來實現(xiàn)錯誤處理是麻煩而且很乏味。一個輸入用戶名的界面在JSP中如下表示:
<input type="text" name="username"
value="<%= loginBean.getUsername() >"/>
輸入如上的字符對于沒有編程理念的HTML編寫者來說是很容易出錯的。Struts在提供了一些自定義標簽來實現(xiàn)上述的功能:
<html:text property="username"/>;
上述表示法并不要很明顯的指定與JAVABEAN相關(guān)聯(lián),它的處理完全由框架實現(xiàn)。
3.3.1索引和映射屬性
JSP頁面中的標簽屬性可以引用JAVABEAN中的屬性。大多數(shù)都是引用簡單類型或簡單對象。但Struts允許你利用Jakarta Commons Beanutils library提供的功能來引用Array,Conllection,Map的單個項。
3.3.2 輸入域的支持
Srust支持如下的輸入域:
1.Checkbox
2.Hidden field
3.Password
4.Radio
5.Reset
6.Select
7.Option
8.Options
9.Submit
10. Text
11. TextArea
在任何情況下,這些標簽必須嵌套在 form標簽中,只有這樣輸入域才知道它要使用那個Bean 。
3.3.3 一些有用的標簽
Iterate
Present
Nopresent
Link
Img
Parametr
3.3.4 自動表單校驗
Strust提供了校驗表單的功能,為了使用此功能,你需要重載ActionForm的如下方法:
validate(ActionMapping mapping,HttpServletRequest request);
當Bean的屬性的數(shù)據(jù)被填充后,在調(diào)用Action的excute方法之前,Controller Servlet來調(diào)用validate方法。Validate方法的執(zhí)行有如下幾種情況:
1.執(zhí)行校驗但沒有錯誤 返回NULL或0長度的ActionErrors實例,Controller Servlet將繼續(xù)執(zhí)行Action的方法。
2.執(zhí)行校驗但有錯誤 返回ActionErrors實例,每一個ActionError有對應(yīng)的錯誤消息關(guān)鍵值。Controller Servlet將把錯誤消息數(shù)組保存到請求級別的上下文中供<html:errors>標簽使用。
3.3.5 Struts校驗器
為表單配置校驗器是很簡單的。
1.ActionForm須繼承ValidatorForm
2.表單所在的JSP頁面須包含<html:javascript>標簽用于客戶端的校驗
3.你需要定義校驗規(guī)則在XML文件中
<form-validation>
<formset>
<form name="logonForm">
<field property="username" depends="required">
<msg name="required" key="error.username"/>
</field>
</form>
</formset>
</form-validation>
4.最后,你必須在struts-config.xml文件中激活ValidatorPlugin
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,
/WEB-INF/validation.xml"/>
</plug-in>
3.4 其他表示層技術(shù)
盡管外觀可以用JSP或Struts的標簽來實現(xiàn),但你仍然應(yīng)該考慮融合其他技術(shù)來提高組件的重用,減少維護工作量,減少錯誤。
3.4.1 特定應(yīng)用標簽
忽略
3.4.2使用包含組合頁面
將一個頁面放在一個JSP文件中是一個普遍的設(shè)計方法,但是許多應(yīng)用需要將應(yīng)用中的不同部分顯示在一個頁面中。例如一個門戶應(yīng)用需要如下功能:
1. 訪問門戶的搜索引擎
2. 訪問門戶的討論區(qū)
3. 用戶感興趣的話題
4. 郵件等待指示器
將這些不同的功能交給不同的開發(fā)者開發(fā),要完成這個門戶應(yīng)用是比較容易的。然后你就可以使用包含( include)來
將它們組合到一個頁面中。有三種不同的包含方式,選擇哪種取決于你希望整個輸出在什么時候整合:
1. <%@ include file="xxxxx" %>
2. <jsp:include page="xxxxx" flush="true" />
3. bean:include
3.4.3 使用Tiles組合頁面
Tiles是一個功能很強的模板庫,它可以將很多tile組合成最終的視圖。以下是設(shè)置向?qū)В?BR>1.創(chuàng)建layout/layout.jsp,它包含標準外觀
<html>
<body>
<tiles:insert attribute="body"/>
</body>
</html>
2.創(chuàng)建你的主頁/index.jsp
<h1>This is my homepage</h1>
3.創(chuàng)建文件/WEB-INF/tiles-defs.xml
<tiles-definitions>
<definition
name="layout"
path="/layout/layout.jsp">
<put name="body" value=""/>
</definition>
<definition name="homepage" extends="layout">
<put
name="body"
value="/index.jsp"/>
</definition>
<tiles-definitions>
4.在文件struts-config.xml中設(shè)置TilesPlugin
<plug-in
className="org.apache.struts.tiles.TilesPlugin">
<set-property
property="definitions-config"
value="/WEB-INF/tiles-defs.xml"/>
</plug-in>
5.在struts-config.xml文件中設(shè)置一個Action指向你的主頁
<action path="/index" type="org.apache.struts.actions.ForwardAction" parameter="homepage"/>
3.4.4 圖片渲染組件
一些應(yīng)用需要動態(tài)產(chǎn)生圖片,有兩種方法符合如下需求:
1. 產(chǎn)生一個執(zhí)行Servlet請求的超鏈接 Servlet將使用圖形庫來產(chǎn)生圖片
2. 將JAVA Applet嵌入在HTML頁面中來產(chǎn)生圖片
3.4.5 文本輸出
一些應(yīng)用需要動態(tài)的產(chǎn)生文本(如XML),因為整個頁面將通過PrinterWriter輸出,我們可以通過設(shè)置PrinterWriter的屬性來做到:
response.setContentType("text/plain"); // or text/xml
PrintWriter writer = response.getWriter();
// use writer to render text
return(null);
3.4.6 Struts EL 標簽庫
Struts基本的標簽都是依賴rtexprvalue(runtime scriptlet expression)來動態(tài)計算屬性
的值,例如,要根據(jù)資源關(guān)鍵值打印來自屬性文件中的信息
<bean:message key='<%= stringvar %>'/> 這樣寫是假定stringvar是JSP中的
腳本變量,如果使用Struts的EL標簽庫就會是如下形式:
<bean-el:message key="${stringvar}"/>
4 創(chuàng)建控制(Controller)組件
4.1 概述
我們已經(jīng)知道如何去構(gòu)建Model和View組件,現(xiàn)在我們將集中到Controller組件。Struts包含了一個映射請求URI到Action類的Servlet。因此你編寫WEB應(yīng)用時在Controller組件這方面要做的工作如下:
1.編寫AtionForm作為Model和View的中介
2.編寫Action(繼承org.apache.struts.action.Action)來處理請求
3.為每一個邏輯請求在struts-config.xml.中編寫一個ActionMapping
4.2 ActionServlet
對于熟悉MVC架構(gòu)的人來講,ActionServlet就代表著 C ? Controller。Controller的任務(wù)是:
1.處理用戶請求
2.根據(jù)用戶請求來決定用戶將要完成什么任務(wù)
3.將Model的數(shù)據(jù)傳到視圖(View)
4.選擇合適的視圖響應(yīng)請求
Controller會將大部分工作放到Request Processor和Action 類中。
4.2.1 請求處理器(Request Processor)
RequestProcessor對每個請求做核心處理的地方,它要做的處理如下:
1. processPath - 確定請求的路徑,以備后面的處理檢索ActionMapping
2. processLocale ? 為請求選擇一個locale
3. processContent - 設(shè)置默認的內(nèi)容(Content)類型.
4. processNoCache ? 設(shè)置響應(yīng)頭:Pragma,Cache-Control,Expires
5. processPreprocess - RequestProcessor讓子類重載實現(xiàn),默認返回真(True),如果子類重載此方法并返回真,則該請求將繼續(xù)處理流程,如果返回假,則意味著你處理了該請求,處理流程直接返回。
6. processMapping - 確定請求所對應(yīng)路徑的ActionMapping
7. processRoles - 保證請求的用戶具備特定的角色
8. processActionForm - 實例化ActioForm并且把它放在適當?shù)淖饔糜蛑小?BR>9. processPopulate - 用請求中的數(shù)據(jù)組裝ActionForm
10. processValidate - 校驗ActionForm中的數(shù)據(jù)
11. processForward - 如果映射是一個轉(zhuǎn)向( Forward)指令,就轉(zhuǎn)向到特定的路徑。
12. processInclude - 如果映射是一個包含(Include)指令,就將映射指定的路徑的輸出結(jié)果包含進來。
13. processActionCreate - 實例化映射指定的Action.
14. processActionPerform ? 執(zhí)行Action的perform或excute方法。
15. processForwardConfig - 最后RequetProcessor使用Action類返回的ActionForward來選擇下一個資源。大多數(shù)的AtionForward將會導航到顯示頁面輸出響應(yīng)。
4.3 ActionForm類
一個ActionForm代表著一個與用戶交互的HTML表單。ActionForm中的屬性來存儲表單中的狀態(tài),并且有g(shù)etter,setter方法來訪問他們。ActionForm可以存儲在session或request的作用域中(默認的是session).如果ActionForm放在session中記得要實現(xiàn)reset方法,以備每次使用ActionForm時都會初始化。Struts根據(jù)請求中的參數(shù)設(shè)置ActionForm的屬性并且把經(jīng)過校驗后的ActionForm傳到Action的execute方法。
當你在編寫ActionForm時必須堅持如下原則:
1.ActionForm本身沒有任何特定的方法被實現(xiàn)。僅僅用來表示它是整個框架中一個特定的角色。ActinForm中只有g(shù)etter,setter方法,并沒有任何商業(yè)邏輯。
2.AtionForm提供標準的校驗機制。如果你重載了ActionForm的validate方法,并且在資源屬性文件中提供了錯誤消息,那么Struts就會自動校驗表單中的數(shù)據(jù)。當然你也可以忽略ActionForm中的校驗,在Action類中來實現(xiàn)校驗。
3.為輸入表單中的每一個輸入定義屬性。輸入域的名稱和ActionForm中屬性的名稱必須符合JAVA規(guī)范。例如一個輸入域的名稱username將會導致ActionForm中的setUsername被調(diào)用。
4.也可以為Form中的按鈕或其他控件定義屬性。當提交表單時這將有利于你知道哪個控件被選中了。
5.把ActionForm當作HTTP和Action之間的防火墻。ActionForm的方法可以校驗所有必須的屬性已經(jīng)存在了并且包含合理的值。如果校驗失敗請求將不會被Action類處理。
6.你可能會放一個Bean的實例在ActinForm中,這樣你就會用到嵌套屬性引用。例如,你可能有一個“customer”在ActionForm中,然后在頁面中用“customer.name”來引用屬性。
4.3.1 DynaActionForm
維護一個具體的ActionForm是要耗費時間的。特別是ActionForm越來越多并且都是校驗一些簡單的屬性時你可能會感覺到一股挫折感。
這個瓶頸通過DynaActionForm會有所減輕。通過在Struts的配置文件中列出屬性,類型和默認值來替代以前的定義一個新類,并且添加getter/setter方法。例如,在struts-config.xml中添加一個UserForm:
<form-bean
name="UserForm"
type="org.apache.struts.action.DynaActionForm">
<form-property
name="givenName"
type="java.lang.String"
initial="John"/>
<form-property
name="familyName"
type="java.lang.String"
initial="Smith"/>
</form-bean>
DynaActionForm支持的數(shù)據(jù)類型:
? java.lang.BigDecimal
? java.lang.BigInteger
? boolean and java.lang.Boolean
? byte and java.lang.Byte
? char and java.lang.Character
? java.lang.Class
? double and java.lang.Double
? float and java.lang.Float
? int and java.lang.Integer
? long and java.lang.Long
? short and java.lang.Short
? java.lang.String
? java.sql.Date
? java.sql.Time
? java.sql.Timestamp
你可以指定成這些類型的數(shù)組,也可以時MAP的具體實現(xiàn)類。
4.3.2 后端映射ActionForm
DynaActionForm根據(jù)配置文件中的屬性在初始化的時候來生成ActionForm。但有時候輸入表單是動態(tài)生成的。因此表單的AtionForm的屬性不能提前知道,所以需要一種新的方法。
Struts允許你將ActionForm屬性存儲在MAP中而不是JAVA的原子對象。
public FooForm extends ActionForm {
private final Map values = new HashMap();
public void setValue(String key, Object value) {
values.put(key, value);
}
public Object getValue(String key) {
return values.get(key);
}
}
在JSP頁面中你可以通過特殊的符號來引用:mapname(keyname)。圓括號在Bean的屬性中表明:
1.ActionForm的所有屬性使用Sring做索引
2.Struts將使用帶String參數(shù)的getter/setter方法來獲取,設(shè)置ActionForm的值。
看如下的例子:
<html:text property="value(foo)"/>
這樣你將會調(diào)用FooForm的getValue方法來得到鍵值為”foo”的值。為了創(chuàng)建一個包含動態(tài)輸入域的表單你會如下做:
<%
for (int i = 0; i < 10; i++) {
String name = "value(foo-" + i + ")";
%>
<html:text property="<%= name %>"/>
<br/>
<%
}
%>
除了后端映射屬性,你還可以創(chuàng)建后端列表屬性。
public FooForm extends ActionForm {
private final List values = new ArrayList();
public void setValue(int key, Object value) {
values.set(key, value);
}
public Object getValue(int key) {
return values.get(key);
}
}
在你的JSP頁面中,你需要用特殊的符號來引用值:listname[index]。
4.4 Action類
Ation有兩個根據(jù)Servlet環(huán)境不同而調(diào)用的方法.
The Action class defines two methods that could be executed depending on your servlet environment:
public ActionForward execute(ActionMapping mapping,
ActionForm form,
ServletRequest request,
ServletResponse response)
throws Exception;
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception;
因為Struts主要用來創(chuàng)建WEB應(yīng)用,所以大多數(shù)項目只用HttpServletRequest。Action主要用來處理請求并且返回對象ActionForward表明控制流將轉(zhuǎn)向哪里(JSP,Action, Tile定義,Velocity模板) 。在MVC/Model2的設(shè)計模式里,Action將完成一下邏輯。
1.校驗用戶Session的狀態(tài)(用戶是否登錄)。
2.校驗表單Bean的屬性。
3.執(zhí)行該請求所需的邏輯處理。
4.修改Server端對象。以備下一個顯示頁面要用。
5.返回一個ActionForward對象來表明哪一個頁面將用來產(chǎn)生輸出。
4.4.1 Action類的設(shè)計方針
1.編寫多線程安全代碼 Controller Servlet只創(chuàng)建一個Action的實例來服務(wù)所有的請求,因此你必須編寫線程安全的Action 類。下面是寫Action類是的兩個基本的方針:
只使用局部變量 編寫線程安全的Action的最重要一點是不要使用實例變量而用局部變量。因為局部變量在每個線程的堆棧上創(chuàng)建,所以不需要考慮多線程的問題。
保存資源 當你分配有限的資源時可能會導致資源匱乏的問題。(比如分配JDBC 連接,這時就要盡可能采用鏈接池的方式)。
2.不要拋出異常,盡量Catch它
如果你的應(yīng)用代碼會拋出異常請Catch住它,記錄他們到應(yīng)用的Log中并且返回一個ActionFoward。
避免寫很長,很復(fù)雜的Action類是明智的。如果你寫很多的邏輯在Action類中,這將會使代碼很難理解,維護,重用。
4.5 異常處理器
當Action的execute方法拋出異常時,你可以定義一個異常處理器來執(zhí)行相應(yīng)的處理。首先你需要一個繼承org.apache.struts.action.ExceptionHandler的類并且重載execute方法。Execute方法將處理異常并且返回一個ActionForward來告訴struts下一步將去哪。然后在struts-config.xml中配置異常處理器:
<global-exceptions>
<exception
key="some.key"
type="java.io.IOException"
handler="com.yourcorp.ExceptionHandler"/>
</global-exceptions>
這個配置說明了當發(fā)生一個IOException時,com.yourcorp.ExceptionHandler.execute將會被調(diào)用。
...........
4.6 插件類
Plugin接口繼承了Ation。它定義了兩個接口init,destroy分別在應(yīng)用啟動和停止時調(diào)用。Plugin的一般用法就是在應(yīng)用啟動時來裝載應(yīng)用的特定數(shù)據(jù)。
在運行時,任何被Plugin裝載的數(shù)據(jù)都可以被Action,或商業(yè)邏輯層的類所使用,不過Plugin并沒有提供訪問這些數(shù)據(jù)的方法。Plugin裝載的數(shù)據(jù)經(jīng)常以預(yù)先定義好的名字放在應(yīng)用的上下文中供其他組件使用。
4.7 ActionMapping的實現(xiàn)
Controller Servlet需要知道如何將某個URI映射到一個Action。ActionMapping中可以找到所需的信息:
Type(類型) - Action類的全名。
Name - Action使用的Form Bean的名字。
Path - 匹配此映射的請求URI.
Unknown - 如果設(shè)置為真,應(yīng)用的所有請求將有此AtionMapping來處理。
Validate - 設(shè)置為真,Action類的validate方法將會被調(diào)用。
Forward - 當映射被調(diào)用時,控制流將會傳遞到那個URI。
4.8 編寫Action Mappings
Controller Servlet怎么知道ActionMapping要做什么呢?編寫一個小的JAVA類并且持有一個ActionMapping的實例,通過setter方法來設(shè)置屬性是可以做到的。不過Struts提供了通過Digester組件解釋XML的方式來實現(xiàn)。
開發(fā)者負責創(chuàng)建一個名字叫struts-config.xml的文件并且把它放在WEB-INF目錄下。
最外層的XML元素必須是<struts-config>,載它的里面有三個比較重要的元素來描述你的Action:
? <form-beans>
? <global-forwards>
? <action-mappings>
<form-beans>
這部分包含了表單Bean的定義。它將用于創(chuàng)建ActionForm。你將使用<form-bean>來定義每個ActionForm,它有如下屬性:
? name: Bean的唯一標識符.
? type: ActionForm的類名。
<global-forwards>
這部分包含了全局性的轉(zhuǎn)向定義。轉(zhuǎn)向定義實際上就是Action的execute方法返回的ActionForward。這些定義將映射邏輯名稱到某種資源(如JSP),當我們改變資源名稱時就不要改所有引用的地方。你使用<forward>來定義轉(zhuǎn)向,它有如下重要的屬性:
? name: 轉(zhuǎn)向的邏輯名稱。
? path: 資源的上下文路徑. 例如: /index.jsp or /index.do
? redirect: True 或 false (默認). ActionServlet 是不是用重定向(redirect)來取代 轉(zhuǎn)向( forward)?
<action-mappings>
這部分包含所有的Action映射。你應(yīng)該使用<action>來定義每一個映射,它包含如下的屬性:
? path: Action所對應(yīng)的上下文路徑.
? type: Action類.
? name: 與Action配套的<form-bean> 元素的名稱.
4.8.1 ActionMapping例子
<struts-config>
<form-beans>
<form-bean
name="logonForm"
type="org.apache.struts.webapp.example.LogonForm" />
</form-beans>
<global-forwards
type="org.apache.struts.action.ActionForward">
<forward
name="logon"
path="/logon.jsp"
redirect="false" />
</global-forwards>
<action-mappings>
<action
path="/logon"
type="org.apache.struts.webapp.example.LogonAction"
name="logonForm"
scope="request"
input="/logon.jsp"
unknown="false"
validate="true" />
</action-mappings>
</struts-config>
4.9 在頁面中使用ActionMapping
在頁面中配置AtionMapping是你無法通過其他方式設(shè)置時的一種方式,它的使用方法為:
<action path="/view" forward="/view.jsp"/>
4.10 在ActionMapping中使用通配符
隨著Struts應(yīng)用的增大,ActionMapping也就越來越多。通配符則可以將幾個相似的AtionMapping組合成一個。
解釋通配符的最好方法是來看一個例子:
<action
path="/edit*"
type="org.apache.struts.webapp.example.Edit{1}Action"
name="{1}Form"
scope="request"
validate="false">
<forward
name="failure"
path="/mainMenu.jsp"/>
<forward
name="success"
path="/{1}.jsp"/>
</action>
在path屬性中的*號可以匹配請求URI/editSubscription,, editRegistration和其他任何以/edit開頭的URI,但/editSubscription/add將不會被匹配。被匹配的部分將會替換AtionMapping的屬性和轉(zhuǎn)向(Forward)中的{1}。
通配符可以包含如下特殊字符:
* 匹配零個或多個字符但不包括/
** 匹配零個或多個字符串并且包括/
\character 反斜杠字符串是轉(zhuǎn)義字符。
4.11 公共的Log 接口
Struts本身并沒有LOG配置,把它交給Commons-Logging是最好的。
5. 配置應(yīng)用
5.1 概述
在你創(chuàng)建Struts應(yīng)用之前,應(yīng)該鋪設(shè)一個好的基礎(chǔ)。在你部署Struts應(yīng)用之前,這里有幾個安裝任務(wù)你必須完成,它包括在Struts配置文件和WEB應(yīng)用部署描述文件中定義相關(guān)的內(nèi)容。
5.2 Struts配置文件
在創(chuàng)建控制組件一章中我們講到了Struts的<form-bean>,<action-mapping>,這些元素在Struts應(yīng)用的開發(fā)中扮演著很重要的角色。其他的配置元素是靜態(tài)的:只需設(shè)置一次。
不變的配置元素是:
? <controller>
? <message-resources>
? <plug-in>
5.2.1 控制器的配置
<controller>允許你配置ActionServlet。
? bufferSize ? 文件上傳時的輸入緩沖區(qū)的字節(jié)數(shù). [4096] (可選)
? className ? 配置Bean的類名. [org.apache.struts.config.ControllerConfig] (可選)
? contentType ? 響應(yīng)輸出內(nèi)容的類型.可能被the Action, JSP, 或其他資源 覆蓋. [text/html] (可選)
? forwardPattern - <forward>元素的path屬性如果以以斜杠開始時映射到上下文相關(guān)的路徑時的替換模式。它可以由如下元素組成:
o $M ? 替換成該模塊的前綴.
o $P ? 替換成<Forward>元素的path屬性.
o $$ - 生成$符號.
$x ? 保留字(x即不是上述字符的其他字符). [$M$P] (可選)
? inputForward - [false] (可選)
? locale - [true] (可選)
? maxFileSize ? 上傳文件的大小.可以以K,M,G為單位(分別代表千,兆,1024兆). [250M] (可選)
? multipartClass - multipart 請求處理類的名稱。 [org.apache.struts.upload.CommonsMultipartRequestHandler] (可選)
? nocache ? 設(shè)置HTTP頭來設(shè)置是否允許緩存. [false] (可選)
pagePattern -
? processorClass - RequestProcessor 子類的類名. [org.apache.struts.chain.ComposableRequestProcessor] (可選)
? tempDir ? 處理文件上傳時的臨時目錄.
5.2.2 消息資源配置
Struts本身支持應(yīng)用的國際化,你可以定義一個或多個<message-resources>在你的配置文件中。
? className ? 配置Bean的類名. [org.apache.struts.config.MessageResourcesConfig] (可選)
? factory ? MessageResourcesFactory的類名. [org.apache.struts.util.PropertyMessageResourcesFactory] (可選)
? key - ServletContext 關(guān)鍵值來存儲此綁定. [org.apache.struts.action.MESSAGE] (可選)
? null ? 設(shè)置為false,將會使找不到相關(guān)資源的鍵值顯示 '???keyname???' 而不是null. [true] (可選)
? parameter ? 資源綁定的名稱. (必須)
5.2.3 插件配置
在Struts的配置文件中使用<plug-in>元素來配置插件。<plug-in>只有一個className的屬性。它是完成了org.apache.struts.action.PlugIn interface接口的類的類名。插件需要配置它自身,所以可用<set-property>來做。
<plug-in className="org.apache.struts.tiles.TilesPlugin">
<set-property
property="definitions-config"
value="/WEB-INF/tiles-defs.xml"/>
</plug-in>
5.3 為應(yīng)用配置模塊
略
5.3.1 模塊配置文件
略
5.3.2 通知控制器
略
5.3.3 切換模塊
略
5.4 WEB應(yīng)用部署描述符
安裝應(yīng)用的最后一步是在web.xml包含Struts組件。
5.4.1 配置ActionServlet實例
配置ActionServlet并加上適當?shù)某跏蓟瘏?shù)
<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>
<load-on-startup>1</load-on-startup>
</servlet>
5.4.2 配置ActionServlet映射
有兩種方法可以定義URL請求將會被Controller Servlet處理:前綴匹配和后綴匹配。
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>/do/*</url-pattern>
</servlet-mapping>
按如上定義,下面就是前綴匹配http://www.mycompany.com/myapplication/do/logon
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
按如上定義,下面就是后綴匹配
http://www.mycompany.com/myapplication/logon.do
5.4.3 配置Struts標簽庫
<taglib>
<taglib-uri>
http://struts.apache.org/tags-bean
</taglib-uri>
<taglib-location>
/WEB-INF/struts-bean.tld
</taglib-location>
</taglib>
<taglib>
<taglib-uri>
http://struts.apache.org/tags-html
</taglib-uri>
<taglib-location>
/WEB-INF/struts-html.tld
</taglib-location>
</taglib>
<taglib>
<taglib-uri>
http://struts.apache.org/tags-logic
</taglib-uri>
<taglib-location>
/WEB-INF/struts-logic.tld
</taglib-location>
</taglib>
<taglib>
<taglib-uri>
http://struts.apache.org/tags-tiles
</taglib-uri>
<taglib-location>
/WEB-INF/struts-tiles.tld
</taglib-location>
</taglib>
<taglib>
<taglib-uri>
http://struts.apache.org/tags-nested
</taglib-uri>
<taglib-location>
/WEB-INF/struts-nested.tld
</taglib-location>
</taglib>