




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、第二章 Struts 入門案例21 從基礎了解Struts現(xiàn)在,程序員們已經(jīng)編寫了很多的Web應用程序。正如我們在第1章中指出的那樣,使用分層體系結構來編寫應用程序可以容易地保證同一個開發(fā)小組的成員對不同的部分有專長,同時還可以保證不同的程序員可以同時在應用程序的不同部分并行進行工作。但是如果小組的全體人員都能從頭至尾的了解Struts開發(fā)的全部流程也是有好處的。在我們開始了解Struts是如何讓不同部分組合在一起協(xié)同工作前,還是從最墓本例子說起。在本章會使用一個簡單但常常被用到的例子用戶登錄和退出的應用程序,來說明Struts的結構。在介紹了應用程序后,我們會將應用程序分解成不同的模塊,并且
2、詳細解說每一個模塊。如果你已經(jīng)在你的開發(fā)機器上安裝了Struts,我們希望你按照本書的介紹一步步完成開發(fā)工作。然后,打完根基后,我們會逐漸地開始構造應用程序。每一部分都根據(jù)你編寫該應用程序的順序給出,而且會詳細到你可以按照它一步步編寫該應用程序(對于我們而言,是多么麻煩的輸人工作呀!)。如果你是在自己的終端上工作,你可以按照我們的順序輸入全部的源代碼。如果不是在自己的終端上工作,你也可以通過閱讀本章來了解過程,因為全部的細節(jié)在本章中都列舉出來了。選擇登錄程序的原因我們的例子允許用戶登錄到應用程序中。一旦用戶登錄進入,則顯示的頁面會改變以反映出該用戶已經(jīng)獲得了使用該應用程序的權限。一般而言,這是
3、用戶登錄到大型應用程序的第一步,這樣應用程序可以使授權的用戶從事其感興趣的動作。但是對于我們而言,用戶登錄的過程已經(jīng)足夠顯示一個Struts應用程序到底是如何工作的。正如表2-1顯示的那樣,選擇用戶登錄程序作為例子的原因主要是該例子具有如下的特性:容易被理解、簡單、自包容以及任何其他應用程序都需要這樣的功能,因此我們僅僅選擇它作為例子。表2-1 選擇登錄應用程序的原因原 因解 釋容易理解大多數(shù)人都曾經(jīng)登錄到某些應用程序中,因此用戶登錄的流程容易理解簡單和自包含一個僅僅允許用戶登錄的例子程序很簡單也容易編寫,同時也是自包含的。它不需要復雜的模塊很多應用程序都需要這樣的模塊我們中的大多數(shù)人都最終要
4、編寫需要某種登錄流程的應用程序,因此我們需要該例程22 簡述登錄應用程序的流程在開始簡述前,要先簡單討論一下該登錄例子程序的范圍以及如何如何遵循這個范圍。接著我們會說明該應用程序使用的不同屏幕,同時說明當用戶登錄時這些屏幕是如何變化的。最后在對本小節(jié)進行了簡單的總結后,我們會回過頭來從整體上對該例子進行分析。 起步我們在此處使用登錄例子程序的目的是使你體驗一下Struts應用程序的具體細節(jié)。為了保證我們專注在自己的目的上,本例子程序僅僅包含了用來顯現(xiàn)框架結構功能的最基本模塊。該例子程序并不包含真正的業(yè)務邏輯、單元測試和漂亮的對話框。對于一個真正的應用程序而言,這些都是很重要的,但是對于我們而言
5、,并不重要,因為我們必須在跑前學會走。本例子程序也是一個完完全全的國際化程序。它并沒有包含那些可以吸引你眼球的HTML元素它僅僅包含了我們需要的方法。當然,你的Struts應用程序可以做得非常漂亮。如果你期望在你自己的機器上運行該例子程序,這可以在本書的站點上尋找該登錄程序Husted。該程序已經(jīng)打包作為一個可以自動升級的WAR包。盡管我們不要求您運行該應用程序,但是它的運行結果應該還算是有趣的。要運行該程序,你所需要做的事情都已經(jīng)包含在本章中了。首先,讓我們從用戶的角度來瀏覽這些頁面。然后,我們再回過頭來看看具體的代碼。222 將會使用的頁面正如表2-2所示,我們的登錄應用程序有兩個頁面:歡
6、迎和登錄頁面頁 面目 的歡迎登錄歡迎用戶,同時給出應用程序的鏈接允許輸入用戶名和密碼如果你已經(jīng)將應用程序配置到自己的機器上,則通過瀏覽器打開下面的頁面就可以看見歡迎頁面http:1ocalhost:8080logon。22. 3 歡迎頁面第一次訪問歡迎頁面時,上面僅僅有一個鏈接。該鏈接具有“Signin”的標簽(圖2.1)。當點擊該鏈接后,登錄頁面就會顯示出來。圖2-1登陸應用程序的歡迎頁面 圖2-2登陸頁面224 登錄頁面正如圖2.2所示,登錄頁面會提交用戶名和密碼給應用程序。檢驗登錄表格是否工作,你可以試試在不輸入任何東西的情況下點擊提交按鈕。則登錄頁面會再次出現(xiàn),但是這次會多出一條消息。
7、正如圖2.3所示。圖2.3登陸頁面提示用戶名和密碼沒有輸入如果輸入了用戶名但是忘記了密碼,在按下提交按鈕后,顯示的消息則又不一樣了。如圖2.4所示。圖2-4登陸頁面提示你需要輸入密碼從用戶的角度而言,下面是關于該流程中需要記住的一些要點:·它立刻告訴用戶是否忘記輸入某些數(shù)據(jù)項。·如果用戶僅僅提交了一個數(shù)據(jù),則它會提示用戶輸入另外一個數(shù)據(jù)。·它在屏幕上再次顯示已經(jīng)輸入的數(shù)據(jù)而不要用戶輸入Back鍵。·如果用戶輸入了正確的用戶名和密碼,則下一個頁面會顯示。如同第1章中的注冊程序一樣,本例子程序使用屬性文件來檢驗登錄信息的合法性。如果你使用從同上下載的例子程序
8、,則可以用任何一個本書作者的名字來登錄進去。如表3-3所示。表2-3 默認的登錄用戶名和密碼用戶名密碼TedCedricGeorgeDavidCraigHustedDumoulinFranciscusWinterfeldtMcClanahan注意:密碼是大小寫敏感的。請確保第一個字母是大寫。225 再次進入歡迎頁面當成功登錄后,歡迎頁面再次出現(xiàn)。但是這次和第一次看見的歡迎頁面有兩點不同。如圖2.5所示。圖2.5首先,頁面上會顯現(xiàn)用戶名。而不是顯現(xiàn)“WelcomeWorld!”。而且,頁面上還多了一個超鏈接。除了“Signin”以外,還有“Sign out”。2,26 退出歡迎頁面如果點擊“Si
9、gn out”鏈接,則我們又回到了最開始的歡迎頁面(如圖2.1所示)。227 特性摘要盡管我們的應用程序很簡單,但是它也顯示了幾個重要技術:·輸出超鏈接。·輸出表格。·校驗輸入。·顯示錯誤信息。·重新填充表格。·顯示可改變的內(nèi)容。盡管不是顯而易見的,但是它還顯示了下面的技術:·在動態(tài)頁面中使用圖像。·重寫超鏈接。在下一節(jié)中,我們將通過研究源程序來說明這些核心特性是如何實現(xiàn)的。23 解剖登錄應用程序此時我們已經(jīng)初步知道了如何使用Struts編寫登錄程序?,F(xiàn)在就要回過頭來仔細看看該程序的構成。我們將說明每一個頁面的代碼
10、,同時也說明相關的組件以及每一個部分是如何工作的。在介紹完全部這些細節(jié)問題后,我們再說明如果使用這些部分組成一個應用程序。231 瀏覽器中歡迎頁面的代碼我們的應用程序是從歡迎頁面開始的。現(xiàn)在先讓我們看看瀏覽器中的歡迎頁面的代碼僅僅是為了看看到底瀏覽器顯示了什么(見代碼清單2.1)。下面標注為黑體的部分是顯示在屏幕上的文字。代碼清單2.1 瀏覽器中歡迎頁面的代碼<HTML><HEAD><TITLE>Welcome World!</TITLE><base href="http:/localhost:8080/logon/pages/W
11、elcome.jsp"></HEAD><BODY><H3>Welcome World!</H3><UL><LI><a href="/logon/logon.do">Sign in</a></LI></UL><IMG src='struts-power.gif' alt='Powered by Struts'></BODY></HTML>如果你是Web應用程序的新手,則要記住
12、的一件重要事情就是這兒僅僅只有標準的HTML語句。實際上,Web頁面上僅顯現(xiàn)那些瀏覽器能夠理解的語言。所有的Web應用程序都受到HTML的限制,因此不能做超過HTML能力范圍的事情。Struts通過使用Velocity模板、JSP以及任何我們愿意使用用來編寫HTML的工具來使得該過程簡單化。但是我們能夠做的事情范圍還是要在瀏覽器能夠理解的標志語言范圍內(nèi)。關鍵字:jsessionid在瀏覽器源代碼中可能有某個東西你認為不是標準的HTML語句。當你第一次該 問該頁面時,“sing-in”鏈接可能看上去實際類似于:<LI><a href=”/logon.do;jsessionid=
13、aa6xkGuY8qc”>Sign in </a</LI>大多數(shù)Web應用程序都需要跟蹤使用該程序的用戶。HTTP對維護用戶登錄提供了一些最基本的支持,但是該方法能力有限,而且也不安全。Java的Servlet技術提供了更好的用戶會話支持。但是需要某種機制跨越不同的HTTP請示來維護會話信息。Jsessionid就是容器用來在HTTP上維護用戶會話的一個關鍵技術。在超鏈接的URL中包含的會話關鍵字的技術被稱為URL重寫。Servlet規(guī)范Sun,JST鼓勵在cookie中維護用戶會話。而當cookie不可用時,URL重寫技術就應當被使用。當瀏覽器第一次向容器發(fā)出請求時,
14、容器并不知道該瀏覽器是否接受cookie。盡管容器向瀏覽器發(fā)出一個cookie,但是直到瀏覽器再次發(fā)出請求前,容器是無法辨別該瀏覽器是否接受了該cookie(HTTP協(xié)議沒有握手的過程)。同時,當前請求的響應也一定也是要輸出的。因此,返回給瀏覽器的第一頁總是會使用URL重寫技術。如果后續(xù)請求中發(fā)現(xiàn)cookie存在,則容器就可以不用URL重寫方法。232 歡迎頁面的JSP源代碼代碼清單2-2 歡迎頁面的JSP源代碼(/pages/Welcome.jsp)<% taglib uri="/tags/struts-bean" prefix="bean" %
15、><% taglib uri="/tags/struts-html" prefix="html" %><% taglib uri="/tags/struts-logic" prefix="logic" %><HTML><HEAD><TITLE>Welcome!</TITLE><html:base/></HEAD><BODY><logic:present name="user"&
16、gt;<H3>Welcome <bean:write name="user"property="username"/>!</H3></logic:present><logic:notPresent scope="session" name="user"><H3>Welcome World!</H3></logic:notPresent><html:errors/><UL><LI><
17、;html:link forward="logon">Sign in</html:link></LI><logic:present name="user"><LI><html:link forward="logoff">Sign out</html:link></LI></logic:present></UL><IMG src='struts-power.gif' alt='Powered b
18、y Struts'></BODY></HTML> 現(xiàn)在我們看看那些標記為黑體的行:<% taglib uri="/tags/struts-bean" prefix="bean" %><% taglib uri="/tags/struts-html" prefix="html" %><% taglib uri="/tags/struts-logic" prefix="logic" %>這些JSP語句等價于
19、Java中的輸入語句,并且使輸入的擴展標簽庫可以被頁面的其他部分使用。代碼<html:base>會生成一個標準的HTMLbase標簽,這使得對圖像等資源的引用與原始JSP頁面的位置相關。你也許已經(jīng)注意到,我們的登錄應用程序有時候引用do這樣的頁面。它們并不是真正存在于服務器上的頁面,而是引用由程序員編寫的Java類或者Action類。這些Action然后會將控制權傳遞給JSP文件來生成http響應。JSP一般都包含類似于圖像或者CSS文件這樣資源的引用。最方便使用這些資源的方法就是使用與JSP模板位置相關的路徑。但是,當Action將控制轉發(fā)給JSP頁面時,它并沒有通知瀏覽器。因此
20、當瀏覽器要使用任何具有相對路徑的資源引用時,它會將Action所在的路徑認為是基本路徑,而不是JSP模板所處的位置。根據(jù)你訪問歡迎頁面的時刻不同,瀏覽器顯示該頁面的位置可能是:http:/localhost:8080/logon/http:/localhost:8080/logon/LogonSubmit.dohttp:/localhost:8080/logon/Logoff.do對于使用動態(tài)內(nèi)容的應用程序而言,這是一個常見的問題。因此HTML規(guī)范提供了base標簽作為解決方法。Struts提供的相對應的html-base標簽會將該JSP的位置作為基本路徑插入JSP文件中。對于從不同位置生成的
21、登錄頁面,如果查看對應的HTML源代碼,你會發(fā)現(xiàn)無論在什么地方,生成的base標簽都是: <base href="http:/localhost:8080/logon/pages/Welcome.jsp">這樣瀏覽器就可以在發(fā)現(xiàn)pages文件夾中的“Power by Struts”圖像?,F(xiàn)在我們看看下面的代碼:<logic:present name="user"><H3>Welcome <bean:write name="user" roperty="username"/&
22、gt;!</H3></logic:present>你可能還記得本歡迎頁面是根據(jù)用戶是否已經(jīng)登錄進入系統(tǒng)來定制化自己的顯示。上面的代碼像是檢查是否在用戶session中存儲了userbean。如果存在該bean,則在歡迎頁面中顯現(xiàn)用戶名。下面的代碼顯示了維護用戶session的重要性。Struts的標簽和Servlet容器會合作來自動維護用戶session(不管用戶瀏覽器是否使用cookie)。對于程序員而言,就如同已經(jīng)在http中內(nèi)建了session一樣這就是框架結構帶來的好處??蚣芙Y構會擴展底層的支持環(huán)境使得程序員可以關注于那些更高層次的任務。<logic:no
23、tPresent scope="session" name="user"><H3>Welcome World!</H3></logic:notPresent>相反的,如果存在user bean,則我們會使用定制化的歡迎頁面。Struts的邏輯標簽都是使用“this”和“notThis”這樣的表單,并沒有提供類似于“Else”這樣的標簽。盡管這意味著更多的條件判斷語句,但是這也簡化了總體語法和標簽的實現(xiàn)代碼。當然,也可以使用其他的擴展標簽庫。用戶并沒有被限制僅僅使用Struts提供的標簽庫。在Struts網(wǎng)站上的可
24、用資源列表中已經(jīng)列出了多個共享的擴展標簽庫ASF,Struts。其中的某個標簽庫就實現(xiàn)了if/then/else語法。如果你想用這種語法,就可以選用該標簽庫。正如我們在231節(jié)中說的那樣,Struts會自動重寫超鏈接來維護用戶會話。它也允許你給超鏈接一個邏輯名,同時將它們存儲在配置文件中。這就如同使用關鍵字來引用數(shù)據(jù)庫中的記錄一樣。記錄中的名字和地址是可以根據(jù)需要進行改變的。而應用程序通過使用關鍵字來找到更新后的記錄。在本例中<LI><html:link forward="logon">Sign in</html:link></LI
25、>我們使用logon這個關鍵字來尋找記錄,它存儲了使用戶登錄進入系統(tǒng)的超鏈接。如果我們以后想改變該超鏈接,僅僅需要在配置文件中改變一次,然后重新啟動應用程序就可以了。頁面在被請求時就會自動使用新鏈接。下面的代碼聯(lián)合使用了<logic:present> 和 <html:link>僅對已經(jīng)登錄的用戶顯現(xiàn)退出的鏈接。<logic:present name="user"><LI><html:link forward="logoff">Sign out</html:link></L
26、I></logic:present>2. 33 歡迎頁面的配置信息Struts使用配置文件來定義應用程序中的很多事情,其中就包括超鏈接的邏輯名。Struts使用的配置文件是一個XML格式的文件,在其啟動時會將它讀到內(nèi)存中,并且根據(jù)其內(nèi)容來創(chuàng)建一個存儲各種對象的數(shù)據(jù)庫。各個模塊都是使用該數(shù)據(jù)庫來提供不同的服務。配置文件的默認名字是struts-configxml。正是因為不同的模塊都使用同一個配置文件,因此我們就應該一開始就定義好該文件?,F(xiàn)在,我們會逐步給出和每一步相關的那部分配置信息。最后,當我們從頭開始構造應用程序時,我們會從整體上了解該配置文件。在開始的歡迎頁面中,我們引
27、用了logon。在配置文件中,它是這樣定義的:<forwardname="logon"path="/Logon.do"/>此處,logon是用來尋找某個超鏈接實際路徑的關鍵字。盡管這兒引用的是Struts的一個Action,但是我們也可以很容易地引用JSP頁面、Velocity模板、HTML頁面或者帶有URl的任何資源。定義URI(uniform resource identifier)是用來定位因特網(wǎng)上或者任何其他計算機網(wǎng)絡上資源的短字符串。資源是指文檔,圖像,可以被下載的文件,電子郵箱或者其他東西。一個URI可以對應服務器上文件系統(tǒng)的路徑
28、,但經(jīng)常是該路徑的別名。Struts應用程序中的URI都是Java類或者Action的別名。因為該路徑定義在配置文件中,因此你可以在任何時候改變其值而不用修改JSP文件。如果你修改并且重新裝載了該配置文件,則再下次生成該JSP對應頁面時就會使用修改后的值。234 瀏覽器中登錄頁面的代碼當你點擊歡迎頁面中的sign-in超鏈接,瀏覽器就會跳轉到登錄頁面。代清單2-3顯示了該頁面在瀏覽器中的代碼。同樣地,下面代碼中的黑體部分就是顯示在屏幕上的文字。代碼清單2.3 登錄頁面在瀏覽器中的代碼<HTML><HEAD><TITLE>Sign in, Please!<
29、;/TITLE></HEAD><BODY><form name="logonForm" method="POST"action="/logon/LogonSubmit.do"><table border="0" width="100%"><TR><TH align="right">Username:</TH><TD align="left"><inp
30、ut type="text" name="username"value=""></TD></TR><TR><TH align="right">Password:</TH><TD align="left"><input type="password" name="password"value=""></TD></TR><
31、TR><TD align="right"><input type="submit" name="submit"value="Submit"></TD><TD align="left"><input type="reset" name="reset"value="Reset"></TD></TR></table></form>
32、<script language="JavaScript" type="text/javascript"><!-document.forms"logonForm".elements"username".focus()/ -></script></BODY></HTML>代碼清單2.4 登錄頁面對應的JSP代碼(pageslogonjsp)<% taglib uri="/tags/struts-html" prefix="
33、html" %><HTML><HEAD><TITLE>Sign in, Please!</TITLE></HEAD><BODY><html:errors/><html:form action="/LogonSubmit" focus="username"><TABLE border="0" width="100%"><TR><TH align="right"
34、;>Username:</TH><TD align="left"><html:text property="username"/></TD></TR><TR><TH align="right">Password:</TH><TD align="left"><html:password property="password"/></TD></TR>&
35、lt;TR><TD align="right"><html:submit/></TD><TD align="left"><html:reset/></TD></TR></TABLE></html:form></BODY></HTML><%-Allow user to submit username and password to logon action.-%>我們還是如同處理歡迎頁面一樣來研究每個黑體部分
36、。首先,和歡迎頁面一樣,下面的代碼使Struts的html標簽庫可以被頁面的其他部分使用:< taglib uri="tagsstrUts-html" prefix="html" >和Struts的action類似,taglib使用的URl也是一個邏輯引用。標簽庫描述符(tag library descriptor TLD)定義在web.xml中。如果我們沒有輸入數(shù)據(jù)時,就提交該表格,并看到一條錯誤信息。下面的標簽就是用來生成該錯誤信息的。如果沒有錯誤信息,則該標簽不會進行任何輸出,也不會出現(xiàn)在最終的頁面上顯示。<html:errors
37、/>而<html:form>標簽會生成一個HTML表單來使用戶輸入數(shù)據(jù)。它同時還會使用簡單的JavaScript來使輸入焦點移動到該表格的第一個輸入框上。而其action屬性指向Struts配置中的某個ActioinMapping對象。該對象決定了使用哪個JavaBean來填充HTML控件。同時該JavaBean也是Struts框架結構的一個ActionForm類。<html:form action="/LogonSubmit"focus="username"><html:text>標簽創(chuàng)建一個HTML文本域輸入
38、框。同時,它還使用該表格對應的JavaBcan中屬性名為username的屬性值來進行自我填充。<TR><TH align="right">Username: </TH><TD align="left"><html:text property="usarname"/></TD>因此,如果該表格因為校驗不通過而被返回,同時最后一次提交的用戶名是Ted,則該標簽的輸出就是:<input type="text" name="usern
39、ame" value="Ted">否則,該標簽就會使用JavaBean中username字段指定的默認值來初始化自己。通常,該默認值是null,但是也可以是任何其他值。同樣,<html:password>標簽會創(chuàng)建一個HTML輸入控制框。<TR><TH align="right">Password:</TH><TD align="left"><html:password property="password"/></TD&
40、gt;當表格被提交時,需要使用兩個對象:ActionForm和Action。程序員負責創(chuàng)建這兩個對象并包含應用程序的細節(jié)信息。正如圖2.6所示,ActionServlet使用配置文件來決定使用哪一個ActionForm和Action。ActionFormActionServlet配置圖2-6 配置文件決定使用哪個ActionForm和Action235 登錄頁面對應的配置部分登錄頁面本身僅僅使用Struts配置文件中的一個元素:/LogonSubmit。該元素會引用兩個元素:app.LogonForm和app.LogonAction。在表2.4中我們依次解釋了這三個元素。表2.4 登錄頁面使用
41、的配置元素元素描述/LogonSubmit封裝了構造和提交一個HTML表格給Struts應用程序的實現(xiàn)細節(jié)app.LogonForm描述了HTML表格使用的屬性app.LogonAction用來完成提交表格流程236 LogonSubmit的源代碼在上一節(jié)中,我們曾經(jīng)提到<html:form>標簽和Struts配置文件緊密合作使HTML的表格更加好用:<html:form action="LogonSubmit"focusc="username">上面的action參數(shù)告訴<html:form>標簽使用哪一個Actio
42、nMapping。在本例中,對應的ActionMapping如下:<actionpath="/LogonSubmit"typex="appLogonAction"name="logonForm"scope="request"validate="true"input="/pages/Logonjsp"/>表2.5說明了上面每一個元素的意義。正如我們在第2章中提到的那樣,Struts使用的很多對象名和屬性名都是很含糊的。例如,上面的name屬性并不是指定該Action
43、Mapping對象的名字,而是指定該ActionMapping使用的JavaBean或者ActionForm的名字。在配置文件中,同樣也定義了form bean:表2.5 ActionMapping的配置元素屬 性功 能path是該ActionMapping的唯一標識符。它包含對應的Web地址,例如http:/localhost:8080/logon/LogonSubmitdotype當請求該路徑時,調(diào)用的Action對象name定義對于一個HTML表格對應的JavaBean(ActionForm)scope該屬性定義了存儲該JavaBean在請求中還是在會話中validate該屬性定義了在調(diào)
44、用由type指定的Action對象前是否調(diào)用由name指定的JavaBean上的validate方法input該屬性定義了當validate方法返回false時控制要轉移的地址<form-beanname="logonform"type="app.LogonForm"/>該元素將邏輯名logonForm和一個指定的Java類app.LogonFonn聯(lián)系在一起。該類應該是ActionForm的子類。在ActionForm類中已經(jīng)提供了一些標準的方法,例如validate方法?,F(xiàn)在我們先看看LogonForm的源代碼,然后再回來看看LogonA
45、ction對象。237 LogonForm的源代碼盡管HTML表格允許用戶輸入數(shù)據(jù),但是并沒有在應用程序中定義何處來存放這些數(shù)據(jù)。當用戶點擊提交按鈕時,瀏覽器收集表格中的數(shù)據(jù),然后以名字值成對的形式發(fā)送給服務器。因此,當用戶在登錄頁面上輸入用戶名和密碼并且提交其輸入后,應用程序知道:username=Tedpassword=LetMeln瀏覽器將所有的數(shù)據(jù)都作為字符串進行提交。在頁面上通過使用JavaScnpt,你可以強制用戶在某些域中輸入數(shù)字或者某種特定格式的數(shù)據(jù),但是這僅僅都是表面現(xiàn)象。用戶輸入的所有東西都最后會轉化為字符串來提交給應用程序,而不是二進制對象。這是瀏覽器和HTML的工作方式
46、,Web應用程序沒有辦法控制這一點。類似Struts這樣的框架結構已經(jīng)盡力來進行處理了。Struts使用ActionForm作為解決方案來處理HTTP的數(shù)據(jù)對。在像Swing這樣的環(huán)境中,數(shù)據(jù)輸入控制都有一個內(nèi)置的文本緩沖區(qū)來對用戶輸入的字符進行校驗。當用戶結束輸入離開該緩沖區(qū)時,緩沖區(qū)中的內(nèi)容就可以被轉換為二進制類型,然后就發(fā)送給后面的業(yè)務邏輯層進行處理。不幸的是,HTTP/HTML平臺并不能提供類似的對輸入進行緩存、校驗和轉換的模塊。因此,Struts提供ActionForm(.action.ActionForm)來彌補Web瀏覽器和業(yè)務邏輯層之間的差距。ActionForm提供了我們需要
47、的緩存、校驗和轉換機制來保證用戶僅僅能輸入期望的數(shù)據(jù)。當提交HTML表格時,Struts控制器獲得提交的名字一值對,然后將它們交給ActionForm來處理。ActionForm是一個和某個HTML表格具有對應屬性的JavaBean。Struts會比較ActionForm的每一個屬性的名字和提交的表單中名字一值對中的名字。當它們匹配時,這控制器使用相應提交的值來設定JavaBean的屬性值。其他的沒有匹配的屬性則被忽略掉。通常那些被忽略掉的屬性則保持其為默認值(一般都是null或者false)。下面是LogonForm的屬性:private String password = null;pub
48、lic String getPassword() return (this.password);public void setPassword(String password) this.password = password;private String username = null;public String getUsername() return (this.username);public void setUsername(String username) this.username = username;大多數(shù)ActionForm類的屬性都這樣。一些程序員使用宏就可以容易地通過輸
49、入屬性名來生成對應的代碼。另外一些可以在編輯器中使用代碼粘貼。而Struts代碼生成器則可以通過使用HTML或者JSP來創(chuàng)建對應的ActionForm。注意 在Struts11中,如果使用DynaActionForm或者集合類型的ActionForm,則創(chuàng)建ActionForm會更加簡單。基本的ActionForm包含兩個標準方法reset和validate。在向?qū)?wizard)工作流中使用ActionForm時,reset方法很有用。如果該對象工作的范圍被設定為請求(request),則可以使用默認的實現(xiàn)。當validate被設定為true時,則在該bean通過HTTP請求進行填充后會調(diào)用
50、它的validate方法。Validate方法經(jīng)常被用來進行主要的校驗工作。該校驗方法僅僅檢查數(shù)據(jù)是“看上去”正確,并且所有需要的值都被提交。再重復一次,對于Swing控件而言,這些工作都是swing,組件在將數(shù)據(jù)傳遞給應用程序前內(nèi)部進行的操作。對于使用Struts的應用程序而言,我們也可以手工進行這些操作,或者通過使用ValidatorForm來實現(xiàn),它也可以通過配置文件進行設置。下面就是LogonForm的validate方法。它僅僅檢查其對應的兩個域是否都輸入了數(shù)據(jù)。如果應用程序有其他的要求,例如用戶名或者密碼的長度有限制,則你可以在該方法中進行檢查。public ActionError
51、s validate(ActionMapping mapping,HttpServletRequest request) ActionErrors errors = new ActionErrors();if (username = null) | (username.length() < 1)errors.add ("username",new ActionError("");if (password = null) | (password.length() < 1)errors.add("password",new A
52、ctionError("error.password.required");return errors;該方法返回的ActionError是Struts框架結構提供的另外一個類。如果vslidate方法返回的ActionError對象既不是null也不是空,則控制器通過一個已定義的鍵將該對象保存在HTTP請求的上下文中。因為<html:errors>標簽也知道該鍵,所以如果該鍵存在,那么該標簽會將錯誤信息提取出來。如果在HTTP請求中不存在該鍵,那么該標簽什么也不做。都是鍵。它們用來從Struts消息資源文件中提取真正的消息。每一個地區(qū),都有一個自己的資源文件。
53、這就簡化了消息的本地化。Struts的消息資源文件同樣使用名字一值對。在我們的例子中,對應的兩項是:Error.Username,required=<li>Username is requxred</li>error.password.required=<ll>Passuord is renuired</li>注意 在Struts11中,還有其他的方法在消息中使用HTML標簽??梢允褂胑rrorsprefix和errorsuffix的新特性來指定類似于<1i></li>這樣的標簽。同時,也可以使用新的消息標簽來代替原有的&
54、lt;html:errors>標簽。該標簽簡化了表現(xiàn)層上標簽的維護工作。就算不需要進行本地化工作,Struts應用程序?qū)⑷肯⒋鎯υ谝粋€地方,這樣用戶就可以在不修改JSP代碼的情況下對這些消息進行瀏覽和修改了。238 LogonAction的源代碼在將數(shù)據(jù)收集進ActionForm對象,并且進行了初步的校驗后,控制器將ActionForm對象傳遞給指定的Action類。Struts應用程序認為你會使用自己的類來完成絕大部分請求工作。Action會保存請求完成后的結果,而JSP文件是用來顯示該結果的。正如我們在第2章中闡述的那樣,這就是被稱為MVC或者Model2的解決方法。其中,Act
55、ion類的工作就是分派HTTP請求。當Struts的sevrlet接受到某個Action的請求時,它就會通過調(diào)用該Action的perform(execute)方法來分派該請求。代碼清單2.5包含了全部代碼。代碼清單2.5 LogonAction類的源代碼package app;n;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import javax.servlet.http.HttpServlet
56、Response;import org.apache.struts.action.Action;import org.apache.struts.action.ActionError;import org.apache.struts.action.ActionErrors;import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionMapping;import org.apache.struts.act
57、ion.ActionServlet;public final class LogonAction extends Action /通過業(yè)務邏輯層校驗用戶身份public boolean isUserLogon(String username,String password)throws UserDirectoryException return(UserDirectory.getInstance().isValidPassword(username,password);/isUserLogon結束public ActionForward perform(ActionMapping mappin
58、g,ActionForm form,HttpServletRequest request,HttpServletResponse response)throws IOException, ServletException /通過Web層獲取用戶名和密碼String username = (LogonForm) form).getUsername();String password = (LogonForm) form).getPassword();/ 校驗用戶名和密碼的正確性boolean validated = false;try validated = isUserLogon(userna
59、me,password);catch (UserDirectoryException ude) /不能連接用戶目錄ActionErrors errors = new ActionErrors();errors.add(ActionErrors.GLOBAL_ERROR,ct");saveErrors(request,errors);return (new ActionForward(mapping.getInput();if (!validated) /身份不匹配ActionErrors errors = new ActionErrors();errors.add(ActionErr
60、ors.GLOBAL_ERROR,new ActionError("error.logon.invalid");saveErrors(request,errors);/返回到input屬性指定的頁面return (new ActionForward(mapping.getInput();/將登陸用戶信息存放在session中/因為以后還要使用HttpSession session = request.getSession();session.setAttribute(Constants.USER_KEY, form);if (servlet.getDebug() >=
61、 Constants.DEBUG) StringBuffer message =new StringBuffer("LogonAction: User '");message.append(username);message.append("' logged on in session ");message.append(session.getId();servlet.log(message.toString();/返回successreturn (mapping.findForward(Constants.SUCCESS);/perfo
62、rm結束 /LogonAction結束Action類處于Struts的頂部,因此它又導入了其他幾個類。我們此時細化每一個被使用的類,這樣便于了解到底這些類是來自哪一個包。import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import javax.servlet.http.HttpServletResponse;import org.apache.str
63、uts.action.Action;import org.apache.struts.action.ActionError;import org.apache.struts.action.ActionErrors;import org.apache.struts.action.ActionForm;import org.apache.struts.action.ActionForward;import org.apache.struts.action.ActionMapping;import org.apache.struts.action.ActionServlet;如果偷懶的話,還可以這樣定義導人:import java.io.*;import javax.s
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 景區(qū)植被養(yǎng)護管理辦法
- 利用改進的蜣螂優(yōu)化算法結合深度學習技術進行高壓斷路器故障診斷的研究
- 服務設計思維在茶飲體驗系統(tǒng)中的應用研究
- 體育機構薪酬管理辦法
- 江西房產(chǎn)抵押管理辦法
- 安全檢查報道
- 硬件加速紋理合成技術-洞察及研究
- 新能源汽車實訓室建設方案及其應用效果評價
- 家具定制行業(yè)最佳實踐指南
- 校園二手市場商業(yè)模式規(guī)劃
- 淹溺診療規(guī)范內(nèi)科學診療規(guī)范診療指南2023版
- PremiereProCC視頻剪輯基礎教程PPT完整版全套教學課件
- 新教材北師大版高中英語選擇性必修第一冊全冊各單元學案(單詞短語句型寫作等知識點匯總)
- 鍍鋅板國家新標準規(guī)定
- 《電工學》“課程思政”教學設計案例
- 數(shù)字時代的商務英語寫作知到章節(jié)答案智慧樹2023年對外經(jīng)濟貿(mào)易大學
- 檢驗科溝通技巧及其它
- 2022年安徽大學科研助理(校聘)招聘60人筆試備考題庫及答案解析
- 四年級閱讀訓練概括文章主要內(nèi)容(完美)
- YY/T 0995-2015人類輔助生殖技術用醫(yī)療器械術語和定義
- GB/T 19352.1-2003熱噴涂熱噴涂結構的質(zhì)量要求第1部分:選擇和使用指南
評論
0/150
提交評論