




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
北京傳智播客教育Struts2高級進(jìn)階內(nèi)容大綱北京傳智播客教育MVC模式的回顧回顧Struts的請求處理時序圖使用超連接的技巧封裝Formbean數(shù)據(jù)時的問題防止表單重復(fù)提交使用復(fù)選框的技巧使用下拉列表框的技巧文件上傳DispatchAction的應(yīng)用Validator框架Struts請求處理過程的源碼分析與digesterStruts2.x與struts1.x的PK北京傳智播客教育Strtuts2和struts1都是遵循MVC的WEB框架,兩者之間是何種關(guān)系?Struts2是在WebWork這個框架基礎(chǔ)上發(fā)展起來的,它不是struts1的升級,它在實現(xiàn)原理和編程應(yīng)用上與struts1都完全不同,可以說是徹底拋棄了struts1的架構(gòu)。雖然WebWork在設(shè)計上卻是要比struts1先進(jìn),但由于用戶習(xí)慣問題,所以很難被普及,只有掛羊頭賣狗肉才會被市場逐步接受,基于這些原因,WebWork開發(fā)團(tuán)隊與Struts1開發(fā)團(tuán)隊開始合作,借struts1之名,行
WebWork之實,推出了Struts2。Struts2相比struts1的劣勢:struts1是老牌框架,應(yīng)用很廣泛,有很好的群眾基礎(chǔ),開發(fā)人員比較好招,項目開發(fā)的風(fēng)險小,成本更低!struts2雖然基于Webwork框架,但是應(yīng)用人群并不多,相對不成熟,未知的風(fēng)險和變化還很多,開發(fā)人員相對不好招,使用它開發(fā)項目的風(fēng)險系數(shù)更大,用人成本更高!Struts2相比struts1的優(yōu)勢:struts2畢竟是站在前輩的基礎(chǔ)設(shè)計出來,它會改善和完善struts1中的一些缺陷,struts1中的一些懸而未決問題在struts2得到了解決。有了struts2,還要學(xué)struts1嗎?必須學(xué)struts1!經(jīng)典面試題:談?wù)剆truts2與struts1的區(qū)別。如果沒學(xué)過struts1,你又怎能回答出兩者的區(qū)別?如果你只會struts2,而不會struts1,誰又會相信你是一個真正有工作經(jīng)驗的人?因為使用
struts2的人基本上都是從struts1切換過來的,至少目前很難找到只懂struts2、還沒用過struts1的程序員。為了讓用人單位相信你有兩年工作經(jīng)驗,為了能更好地找到工作,你還必須學(xué)好
struts1,至少目前是這樣的!學(xué)習(xí)struts1,才能更好地學(xué)習(xí)struts2,才能更好地理解web框架中的那些設(shè)計思想是怎樣發(fā)展出來的,這就是對比學(xué)習(xí)法。并且,web框架的思想是相通的,學(xué)好一個框架后再學(xué)另一個框架,并不需要很多時間。Struts2的入門理論StrutsPrepareAndExecuteFilter用戶請求北京傳智播客教育ActionActionAction…struts.xmlWeb容器web.xml準(zhǔn)備struts2的學(xué)習(xí)和開發(fā)環(huán)境北京傳智播客教育預(yù)備工作演示訪問或直接訪問,下載和解壓struts開發(fā)包(目前版本為struts2.3.X)參看Struts2自帶的例子,搭建環(huán)境是一定要參照該例子,以便省去細(xì)節(jié)的記憶之苦和提高工作效率!!!安裝和配置好帶MyEclipse插件的eclipse或eclipse
for
JEE之類的
IDE工具,并測試驗證該IDE可以成功開發(fā)和部署Web項目。Struts2開發(fā)步驟:1.新建web工程2.參照開發(fā)包自帶的例子把StrutsPrepareAndExecuteFilter及相關(guān)類引進(jìn)來3.參照開發(fā)包自帶的例子在web.xml文件中配置
StrutsPrepareAndExecuteFilter4.參照開發(fā)包自帶的例子編寫Action類和配置struts.xml文件這里必須了解Action類的基本編寫規(guī)范和其配置原理,祥見下頁。北京傳智播客教育體驗Struts2入門之HelloWorld編寫不依賴任何三方包的Action類每一個請求最終是要映射給Action類中的一個方法去處理,在Action類中包含一個處理請求的方法,后面配置兩個<action>元素都映射到這一個方法的訪問路徑,以便對比了解struts.xml文件中的配置信息。按照MVC架構(gòu),Action執(zhí)行完后要返回顯示的結(jié)果視圖,所以,Action中的請求處理方法要返回一個邏輯名稱來表示它要顯示的結(jié)果視圖,即方法的返回值類型為代表邏輯名稱的字符串。這里暫時返回null或字符串’none’,用ServletActionContext.getResponse進(jìn)行輸出。在struts.xml配置文件中配置Action類一個好的web開發(fā)經(jīng)驗就是對各個訪問路徑按模塊進(jìn)行歸類命名,即通過訪問路徑就能體現(xiàn)出當(dāng)前資源屬于哪個模塊,struts.xml文件中的配置信息使用package對Action進(jìn)行分類和管理,每個包都要對應(yīng)一個不同的訪問路徑前綴,從而強制用戶實施了路徑歸類命名的好習(xí)慣。我們應(yīng)將同一個模塊下的Action采用相同的包。Struts2的通用訪問路徑:<PackageNamespace>/<ActionName>.<Extension>只要掌握了struts2訪問路徑的映射原理,也自然就知道如何編寫Action的配置信息了。訪問路徑的默認(rèn)擴(kuò)展名為.action或者不使用擴(kuò)展名。包與Action的定位要分為兩個方面來單獨思考:首先了解如何定位包,然后再了解如何查找Action。根據(jù)訪問路徑中的包名部分在struts.xml等配置文件中查找對應(yīng)的包,如果不存在相應(yīng)的包,則查找上一層的包名,依此遞推,直到追溯出一個存在的最匹配的上層包名。注意,只要一旦追溯到了一個最匹配的上層包名,不管這個包中是否存在要訪問的Action,都不會再追溯更上層的包名了。一旦定位到了某個包下,接著就會在這個包中查找action。由于struts會追溯上層包的特點,所以,用某個包的名稱空間的子目錄形式也可以訪問到該包中的Action,前提是該子目錄不存在對應(yīng)的名稱空間。namespace屬性可以設(shè)置為空字符串””,即為默認(rèn)名稱空間,如果
struts2定位到的包名中不存在當(dāng)前要訪問的Action
,struts2接著還會在默認(rèn)名稱空間尋找該Action,只有在默認(rèn)名稱空間的包名中還沒找到該
action時,才報錯action找不到的錯誤。注意區(qū)分默認(rèn)名稱空間與根(/)名稱空間的區(qū)別,根(/)名稱空間就是一個普通的名稱空間,與”/user/admin”、”/user”等一樣,都是具體的包名,只是它是最頂層的名稱空間,當(dāng)struts在某個子名稱空間對應(yīng)的包中沒有查找action時,不會再去根(/)名稱空間中查找,但會在默認(rèn)名稱空間中繼續(xù)查找該action。北京傳智播客教育配置結(jié)果視圖與視圖工作原理在struts.xml配置文件中配置結(jié)果視圖,即在struts.xml配置文件中將請求處理方法返回的字符串關(guān)聯(lián)到某個具體的視圖資源上,這種映射方式可以實現(xiàn)action程序代碼與返回的jsp頁面名稱的解耦。局部視圖:在<action>元素中配置<result>元素全局視圖:在<global-results>元素中配置<result>元素<result>元素的三個要素:類型、名稱和若干參數(shù)如何查看各類視圖的信息:查看struts幫助文檔中的guides欄目中的results部分。查看struts-default.xml文件中的struts-default這個包中的各個<result-type>元素的定義,即可知道各個result類型名稱具體來自哪里。根據(jù)<result-type>元素中定義的類名,查看視圖類的API幫助文檔,可以知道視圖類需要實現(xiàn)Result接口,并可以看到各個視圖類支持的配置參數(shù)和缺省的參數(shù)。例如,查看ServletDispatcherResult類,用location參數(shù)配置jsp頁面資源位置。實驗指導(dǎo):編寫一個jsp頁面,并將該jsp頁面映射到先前配置的那個<action>元素中一個默認(rèn)類型的局部result視圖上,在Action類的sayHello方法中返回“success”字符串。程序運行報告錯誤后,引出每個視圖類型都是一個Java類的講解,再說一個包可以繼承另外一個包的定義,引出默認(rèn)包的繼承講解。把sayHello方法再映射到另一個<action>元素上。在另外這個<action>元素中配置全局result對應(yīng)到先前的JSP頁面,全局result的type要設(shè)置為plaintext。訪問這兩個action配置路徑,分別顯示出了jsp頁面的結(jié)果內(nèi)容和原始內(nèi)容,用于對比講解type屬性的作用。配置清單參看下頁北PP京T傳。智播客教育入門HelloWorld的配置清單北京傳智播客教育<package
name="default"
namespace="/hello/world"extends="struts-default"><global-results><result
type="
plainText"
name=“success"><param
name="location">/WEB-INF/page/view.jsp</param></result></global-results><action
name="view1Action"
class="cn.itcast.struts2demo.HelloWorldAction"
method="sayHello"><result
type="dispatcher"
name=“success"><param
name="location">/WEB-INF/page/view.jsp</param></result></action><action
name="view2Action"
class="cn.itcast.struts2demo.HelloWorldAction"
method="sayHello"><result
type="dispatcher"
name=“success"><param
name="location">/WEB-INF/page/view.jsp</param></result></action></package>讓eclipse輔助提示struts.xml文件的編寫北京傳智播客教育如果eclipse能夠?qū)truts.xml文件中的各個元素的編寫進(jìn)行輔助提示,這就可以事半功倍了,struts2的開發(fā)老手和新手都很有必須掌握這一技巧。如果計算機連接上了internet,eclipse能根據(jù)dtd文件的
url地址自動下載和緩存該dtd文檔,以后沒有連接上
internet也可以自動提示,這可以通過查看eclipse的cache看到。在struts包中找到struts.xml文件的dtd文件,將其復(fù)制到某個目錄中,然后配置xmlcatalog,注意key的類型要選用url,key則設(shè)置為連網(wǎng)時要訪問的那個url地址。常量配置北京傳智播客教育在根元素<struts>下可以使用constant子元素配置常量。從strut2的核心jar包內(nèi)的org.apache.struts2包下的perties文件中可以看到各個常量的注釋說明,典型幾個常量:<constantname=“struts.action.extension”value=“do,go”/>配置訪問Action的后綴,可以配置多個后綴名。提示:perties文件中為該常量配置了一個空字符
串。常量struts.devMode可以讓struts在控制臺中打印出更多的信息和重新加載配置文件。常量struts.configuration.xml.reload可以讓struts重新加載配置文件,但不會導(dǎo)致web應(yīng)用重新啟動。常量struts.i18n.encoding可以設(shè)置struts內(nèi)部進(jìn)行各種字符編碼處理時的字符集編碼,例如,用于獲取請求參數(shù)時的解碼、讀取靜態(tài)文本文件和輸出靜態(tài)文本文件時的字符解碼和編碼。<constantname=“struts.enable.DynamicMethodInvocation”value=“false”/>可以配置不支持動態(tài)方法調(diào)用。常量可以在下面多個文件中進(jìn)行定義,struts2加載常量的搜索順序如下,后面的設(shè)置可以覆蓋前面的設(shè)置:perties文件struts-default.xmlstruts-plugin.xmlstruts.xmlperties(為了與webwork向后兼容而提供)web.xmlStruts.xml中的默認(rèn)值與更多配置細(xì)節(jié)北京傳智播客教育在根元素<struts>下可以使用include子元素引入其他的配置文件,這樣可以將各個模塊分散在不同的配置文件中進(jìn)行配置。
package的name屬性用于唯一標(biāo)識這個包;namespace說明訪問其中的各個action時在路徑中要增加的目錄前綴;extends屬性用于說明這個包繼承了另外一個包的定義,自己定義的包通常要繼承struts-default.xml文件中定義的struts-default包;abstract屬性說明這個包為抽象的,其中不能有action元素,struts-default包就是抽象的。package的namespace屬性可以不設(shè)置,即為默認(rèn)名稱空間。package元素下可以定義全局視圖,如果兩個package要共享相同的全局視圖,那么為它們定義一個相同的父包。<action>元素的method屬性可以不設(shè)置,默認(rèn)為execute;class屬性可以不設(shè)置,默認(rèn)為
ActionSupport。<result>元素的type屬性和name屬性都可以不設(shè)置,默認(rèn)值分別為dispatcher和success。當(dāng)<result>元素中只有默認(rèn)的<param>子元素要設(shè)置時,可以將該<param>子元素中的內(nèi)容直接寫在<result>標(biāo)簽中。在<package>元素下配置<default-action-ref>子元素,用于說明在該包下不存在的action路徑映射,都可以統(tǒng)交給一個默認(rèn)的<action>元素去處理。在<package>元素下的<default-class-ref>子元素,用于配置該包下的<action>元素的class屬性的默認(rèn)值,前面說的默認(rèn)值為ActionSupport正是通過這個元素配置的。使用Config
Browser
Plugin瀏覽已經(jīng)裝載的配置信息和列出各個包名稱空間下的所有Action的訪問鏈接。動態(tài)方法調(diào)用北京傳智播客教育如果Action中存在多個方法時,在struts.xml文件中可以只配置一個<action>元素,訪問路徑可以在緊跟action名稱的后面增加一個感嘆號(!)后接著指定要訪問的方法名,這就是動態(tài)方法調(diào)用,語法格式如下:<PackageNamespace>/<ActionName>!<MethodName>.<extension>舉例:可以通過常量struts.enable.DynamicMethodInvocation關(guān)閉動態(tài)方法調(diào)用。盡量不要使用動態(tài)方法調(diào)用,可以采用*通配符的方式進(jìn)行替代。*通配符北京傳智播客教育在action元素的name屬性中可以使用*通配符,它可以匹配除了/以外的多個連續(xù)字符,在action元素的class和method屬性以及result元素中可以引用*通配符在訪問期間實際匹配的內(nèi)容,例如:方式1:<action
name="view6*"
class="cn.itcast.struts2demo.HelloWorldAction"
method="{1}"><result>/WEB-INF/page/{1}.jsp</result></action>方式2:<action
name="view7_*"
class="cn.itcast.struts2demo.HelloWorldAction"
method="{1}"><result>/WEB-INF/page/{1}.jsp</result></action>如果*匹配的內(nèi)容為空,則調(diào)用execute方法;對于采用下劃線連接*的方式,如果訪問路徑中沒有為*部分指定內(nèi)容,那么在訪問路徑中還可以省略下劃線。使用*通配符可能導(dǎo)致有多個action元素與一個訪問路徑匹配,這時候以排在配置文件中最后的配置項為準(zhǔn),所以更具體的模式應(yīng)在更不具體的模式之后進(jìn)行配置。請描述<action
name=“*”><result>/WEB-INF/{1}.jsp</result></action>的含義。StrutsPrepareAndExecuteFilter的功能北京傳智播客教育是對struts2.0.x的FilterDispatcher的替代,結(jié)合了StrutsPrepareFilter與StrutsExecuteFilter的功能。目前提供的文檔對此類的描述甚少,可以參看FilterDispatcher的幫助文檔來獲得部分信息。查詢ActionMapper是否該攔截此請求,對于攔截的請求,此過濾器處理后,將終止過濾器鏈。如果其他Filter也要處理struts2攔截的請求,必須放在此
Filter之前進(jìn)行配置。處理符合/struts/*路徑格式的靜態(tài)內(nèi)容的訪問請求,將其映射到template、static和org.apache.struts2.static等包下。其他的Filter通常要位于StrutsPrepareAndExecuteFilter之前,如果其他的Filter要訪問Struts的特性,這時候不要使用
StrutsPrepareAndExecuteFilter
,而是使用StrutsPrepareFilter與StrutsExecuteFilter,并讓其他的Filter應(yīng)位于兩者之間。查看和略讀StrutsPrepareAndExecuteFilter的源代碼,包括在哪些目錄下查找靜態(tài)資源的有關(guān)代碼。分析一個action路徑的結(jié)果視圖轉(zhuǎn)發(fā)給另外一個action路徑時為何不能直接使用dispatcher類型,而是要使用chain類型。Struts2框架的工作原理北京傳智播客教育訪問Servlet
API北京傳智播客教育調(diào)用ServletActionContext的各個方法getActionMapping()getPageContext()getRequest()getResponse()getServletContext()Action實現(xiàn)如下接口,struts框架則會為其注入相應(yīng)的Servlet
API對象:ServletRequestAwareServletResponseAwareServletContextAware攔截器北京傳智播客教育Struts2為一個Action自動注入的各種功能都是通過各種攔截器實施上去的。在<action>中使用<interceptor-ref>元素引用攔截器或攔截器棧,在struts-default.xml文件中查看和了解默認(rèn)包中的默認(rèn)攔截器棧的配置。在<package>中使用<interceptors>元素配置<interceptor>或<interceptor-stack>在<package>中使用<default-interceptor-ref>元素為該包中的所有action配置默認(rèn)攔截器,每個包只能指定一個默認(rèn)攔截器。一旦為某個action顯式指定了某個攔截器,則所屬包中定義的默認(rèn)攔截器將不起作用。通過一個實驗來演示ServletConfig攔截器用于調(diào)用HttpServletRequestAware、HttpServletResponseAware等接口的方法。自定義一個進(jìn)行性能統(tǒng)計或權(quán)限判斷的攔截器,性能統(tǒng)計攔截器要實現(xiàn)
erceptor.Interceptor接口。權(quán)限判斷攔截器繼承
MethodFilterInterceptor類,這樣只對某些方法起作用,而對其他方法不起作用。借助AnnotationWorkflowInterceptor用注解方式實現(xiàn)攔截器的功能@Before@BeforeResult@After了解ValueStack與<s:debug>標(biāo)簽北京傳智播客教育Struts2框架使用OGNL作為默認(rèn)的表達(dá)式語言,先用<s:property>標(biāo)簽體驗一下ognl表達(dá)式和調(diào)動學(xué)習(xí)熱情,例如,顯示Action中的一個屬性和顯示一個請求參數(shù)。OGNL表達(dá)式就是針對一個稱為OGNLContext的Map對象和一個稱之為OGNL根對象進(jìn)行操作的語言,OGNL表達(dá)式可以尋址Context內(nèi)部的對象和直接調(diào)用根對象的屬性或方法。Struts2中設(shè)置的OGNL
根對象為CompoundRoot,OGNL
Context的Map對象和
CompoundRoot封裝在一個ValueStack對象中。由于OGNLContext是一個Map對象,不算什么新知識,不用專門學(xué)習(xí)了,所以,學(xué)習(xí)OGNL的重要第一步就是要先了解ValueStack和CompoundRoot
。ValueStack內(nèi)部封裝的CompoundRoot是一個繼承了ArrayList實現(xiàn)的堆棧,
OGNL
Context中也保存了ValueStack的引用。(見下頁的關(guān)系圖)<s:debug>標(biāo)簽可以在jsp頁面中查看CompoundRoot和OGNL
Context
map中的信息。如果不經(jīng)過struts2的過濾器攔截就直接訪問jsp頁面,那么其中使用的<s:debug>,<s:text>,<s:property
value="%{getText()}">等struts2標(biāo)簽都會報告TagUtil.getStack方法拋出的異常。獲取ValueStack對象的代碼如下:ValueStack
stack=
ActionContext.getContext().getValueStack();ValueStack被存儲在了request作用域中,可以通過request.getAttribute(…)的方式獲得。ValueStack提供了如下一些方法管理其內(nèi)部的堆棧:push和pop方法分別對堆棧進(jìn)行壓棧和彈棧。set方法用于在棧頂?shù)腗ap對象中設(shè)置一個條目,如果棧頂不是一個Map對象,則創(chuàng)建一個Map對象并將其壓入棧頂。實驗結(jié)果:set方法不能設(shè)置棧頂?shù)钠胀↗avaBean對象的屬性。ValueStack及關(guān)聯(lián)的Context示意圖Struts2框架為OGNL
Context內(nèi)部初始填充的幾個重要的key:parameters一個map對象request
一個map對象session
一個map對象application
一個map對象attr
一個map對象北京傳智播客教育ActionContext——封裝Action所需的環(huán)境信息和數(shù)據(jù)人類的環(huán)境提供了人類生活所需的一切,Action環(huán)境則提供了Action所要的一切!Action的環(huán)境即為ActionContext對象。在Action內(nèi)部調(diào)用ActionContext.getContext()方法即可獲得該線程范圍內(nèi)共享的ActionContext對象。ActionContext內(nèi)部封裝了ValueStack對象及其相關(guān)的OGNL
Context的Map對象,getValueStack()和getContextMap()方法分別得到ValueStack對象和及其相關(guān)的Context,三者之間的關(guān)系圖如下:ActionContext提供了各種針對ValueStack關(guān)聯(lián)的Context的便利操作方法,包括直接返回該Context對象內(nèi)部存儲的各個Map集合對象的便利方法:put()方法和get()方法就是往該Context
Map對象中添加數(shù)據(jù)和取數(shù)據(jù)。getApplication()得到application域中的所有attribute的map對象;getSession()得到代表session域中的所有attribute的map對象;getParameters()得到代表所有請求參數(shù)的map對象;getLocale()得到當(dāng)前用戶的Locale信息,是綜合了session中保存的Locale與瀏覽器請求消息中的Locale的結(jié)果。ServletActionContext類繼承了ActionContext類,它額外再提供了一些方便的方法,主要是直接返回Servlet有關(guān)的API,例如,返回HttpServletRequest和HttpServletResponse等,它內(nèi)部還是調(diào)用
ActionContext內(nèi)部保存的那個OGNL
Context
Map對象。北京傳智播客教育OGNL基礎(chǔ)與ValueStack的有關(guān)方法北京傳智播客教育OGNL(對象圖導(dǎo)航語言,ObjectGraphNavigation
Language)是一種用于從
ValueStack對象內(nèi)部封裝的OGNLContextMap和CompoundRoot根對象中獲取值的表達(dá)式,最基本的語法如下:1.可以用#key的形式訪問OGNLContextMap中的各個key對應(yīng)的對象,并可以采用點(.)操作符進(jìn)行多級導(dǎo)航調(diào)用對象的屬性和方法,例如,#application、#session.attr1、#key1.sayHello();對于map對象,map.attr不是map.getAttr()方法,而是表示
map.get(“attr1”)。2.如果要訪問根對象的屬性或方法,則可以省略#key,直接訪問該對象的屬性和方法。
struts2修改了OGNL表達(dá)式的默認(rèn)屬性訪問器,它不是直接訪問根對象CompoundRoot的屬性或方法,而是在CompoundRoot內(nèi)部的堆棧中所有對象上逐一查找該屬性或方法,搜索順序是從棧頂對象開始尋找,依次往下,直到找到為止,例如,sayHello()表示調(diào)用堆棧中某個對象的sayHello()方法。3.特例:如果引用名前面沒有#,且CompoundRoot中存儲的各個對象沒有該屬性,則把整個表達(dá)式當(dāng)作OGNL
Context
Map中的某個key來檢索對應(yīng)的對象。ValueStack提供了如下一些方法管理其內(nèi)部的堆棧和關(guān)聯(lián)的Context:setValue為ognl表達(dá)式尋址到的對象設(shè)置屬性值。findValue方法使用OGNL表達(dá)式獲取結(jié)果。findString方法對findValue方法獲取的結(jié)果調(diào)用轉(zhuǎn)換器轉(zhuǎn)成字符串,如果該對象的類型沒有相關(guān)轉(zhuǎn)換器,則調(diào)用toString方法,并返回結(jié)果字符串。一個特殊之處:如果不用#前綴訪問OGNL
Context
Map中的對象,則該對象必須是String類型。<s:property>、<s:push>和<s:bean>標(biāo)簽北京傳智播客教育<s:property>標(biāo)簽用于輸出某個OGNL表達(dá)式的值,并進(jìn)行HTML和XML實體轉(zhuǎn)換,可以認(rèn)為其內(nèi)部使用的是ValueStack對象的findString()方法。如果沒有設(shè)置value屬性,則輸出ValueStack棧頂?shù)膶ο螅刃в谳敵觥皌op”這個特殊的OGNL表達(dá)式,”top”表示棧頂?shù)膶ο蟆H绻捎貌患?前綴的方式輸出Context中的某個對象,這個對象必須是String類型,以此可以說明該標(biāo)簽內(nèi)部調(diào)用的是ValueStack.findString()方法。<s:push>標(biāo)簽用于將OGNL表達(dá)式的值壓入棧頂。<s:bean>標(biāo)簽用于實例化一個JavaBean對象,并將其壓入棧頂。如果設(shè)置了var屬性,還會將實例化的對象存儲進(jìn)ValueStack關(guān)聯(lián)的Context
Map中。實驗步驟:用<s:push>標(biāo)簽把Context中的一個對象壓入棧頂,再查看<s:debug>標(biāo)簽的執(zhí)行結(jié)果,注意<s:debug>標(biāo)簽要位于<s:push>標(biāo)簽對之間。用<s:bean>標(biāo)簽用于實例化一個java.util.Date實例對象,查看<s:debug>標(biāo)簽的執(zhí)行結(jié)果,注意<s:debug>標(biāo)簽也要位于<s:push>標(biāo)簽對之間;接著設(shè)置其var屬性,再查看<s:debug>標(biāo)簽的執(zhí)行結(jié)果。北京傳智播客教育<s:set>、<s:if/elseif/else>與<s:iterator>標(biāo)簽<s:set>標(biāo)簽用于將某個值存入指定范圍域中,通常用于將一個復(fù)雜的
ognl表達(dá)式用一個簡單的變量來進(jìn)行引用。scope屬性:指定變量被放置的范圍,該屬性可以接受application、session、request、
page或action。該屬性的默認(rèn)值為action,文檔說即表示同時存儲進(jìn)request作用域和
OGNL
Context中,但實驗結(jié)果是只存儲進(jìn)了OGNL
Context
Map中。實際上文檔時對的,只是s:debug沒有顯示出來而已(yuanyongzhi)。value屬性:賦給變量的ognl表達(dá)式結(jié)果.如果沒有設(shè)置該屬性,則將ValueStack棧頂?shù)闹蒂x給變量。<s:if/elseif/else>等標(biāo)簽用于判斷test屬性中指定的ognl表達(dá)式的結(jié)果是否為true,為真則執(zhí)行標(biāo)簽體中的內(nèi)容。<s:iterator>標(biāo)簽用于迭代一個OGNL集合,并逐一將迭代出來的元素壓入棧頂和彈棧。status屬性:創(chuàng)建代表當(dāng)前迭代狀態(tài)的IteratorStatus對象,并指定將其存儲進(jìn)
ValueStack
Context中時的key。輸出迭代后的ValueStack棧頂對象的屬性并利用迭代狀態(tài)的示例代碼如下:<s:iterator
value="#request"
status="status"><tr
class='<s:property
value="#status.odd
?
'odd':'even'"/>'
><td><s:property
value="key"/>::::<s:property
value="value"/></td></tr></s:iterator>OGNL的語法細(xì)節(jié)參看ognl的參考手冊類似EL表達(dá)式的JavaBean屬性訪問和索引訪問,例如,可以用”#parameter.id[0]”或”#parameter[‘id’][0]”訪問名稱為id的請求參數(shù)。問題:ValueStack
Context有一個名稱為
com.opensymphony.xwork2.ActionContext.locale的key,使用一個怎樣的OGNL表達(dá)式可引用這個key對應(yīng)的值對象呢?答:可以先從request中得到valueStack,再從
ValueStack獲得context,再從context中用[]的方式獲取。支持靜態(tài)方法和靜態(tài)屬性的訪問調(diào)用,表達(dá)式的格式為@帶包的類全名@方法名或?qū)傩悦纾篅java.lang.String@format(‘foo
%s’,variant)或@java.util.Locale@US;session.attribute[“foo”]等效于session.getAttribute(“foo”)方法。在OGNL中可以寫很大的整數(shù),例如,<s:property
value="%{1111H.bitLength()}"/>,而在java中則不能直接寫1111這么大的整數(shù)。對當(dāng)前值可以進(jìn)一步操作,<s:propertyvalue=“110H.intValue().(#this<112?#this*2:#this/2)”/>,其中.(#this…..)部分相當(dāng)于定義了一個匿名方法,并調(diào)用這個匿名方法,方法的代碼就是()里面的內(nèi)容。并且在()里面會把前面的運算結(jié)果作為root來處理。Struts2擴(kuò)展的特殊功能[n]表示從原來堆棧中截取一個子堆棧并對這個子堆棧進(jìn)行操作,子堆棧為原始堆棧的棧頂開始的索引號為n的元素一直到棧底,例如,[1].age表示從原始堆棧中的索引號為1
的對象(即第二個對象)開始查找age屬性,以找到的第一個為準(zhǔn)。top表示ValueStack棧頂?shù)膶ο螅琜0]北.to京p傳和智to播p表客示教育同一個對象。OGNL的語法細(xì)節(jié)——集合對象與操作北京傳智播客教育{}用于創(chuàng)建List集合對象,其中的各個元素之間用逗號分隔。<s:set
value=“{1,3,5,7}”
var=“l(fā)ist”/>采用類似Java的語法創(chuàng)建數(shù)組<s:set
value=“new
int[]{1,3,5,7}”
var=“array”/><s:set
value=“new
int[4]”
var=“array”/>#{}用于創(chuàng)建Map集合對象,其中的各個元素之間用逗號分隔,元素的key和value之間采用冒號分隔。另外,還可以指定Map實例對象的類型。<s:set
value=“#{‘lhm’:96,’zxx’:93,’xpc’:97}”<s:setvalue=“#@java.util.LinkedHashMap@{‘lhm’:96,’zxx’:93,’xpc’:97}”in與not
in操作符用于判斷某個值是否位于某個集合中。集合偽屬性:size/isEmpty/iterator/keys/values/next/hasNextOGNL的語法細(xì)節(jié)——集合的投影與過濾北京傳智播客教育投影就是拿著集合中的每個元素去進(jìn)行運算,各個元素運算的結(jié)果組成一個新集合,新集合中的元素個數(shù)與原始集合中的元素個數(shù)相同。<s:property
value=“persons.{name}”/><s:property
value=“{5,3,2}.{#this*2}”/>過濾就是拿著集合中的每個元素去進(jìn)行布爾運算,運算的結(jié)果為true,則將該元素保存到新集合中去。?:獲得所有符合邏輯的元素。
<s:property
value=“{5,3,2}.{?
#this
}”/>^:獲得符合邏輯的第一個元素。
<s:property
value=“{5,3,2}.{^
#this>3
}”/>$:獲得符合邏輯的最后一個元素。
<s:property
value=“{5,3,2}.{$
#this>2
}”/>OGNL的語法細(xì)節(jié)——類型轉(zhuǎn)換北京傳智播客教育轉(zhuǎn)換成boolean類型整數(shù)0轉(zhuǎn)換為false值為0的字符轉(zhuǎn)化為falsenull對象轉(zhuǎn)化為false投影和選擇操作符(e1.{e2}ande1.{?e2})前面的內(nèi)容會被轉(zhuǎn)換成集合數(shù)字會被轉(zhuǎn)換成從0開始到比該數(shù)字小1的所有數(shù)字的集合。單個對象被轉(zhuǎn)換成僅僅只含有該對象的集合。Map會被轉(zhuǎn)化成其values屬性返回的集合在配置文件中使用OGNL北京傳智播客教育在struts2的各種配置文件中也可以使用OGNL,只需要將OGNL表達(dá)式套在${}中,即${ognl表達(dá)式}。總結(jié)列表:對${ognl}的總結(jié)涉及一些大家暫時還沒學(xué)習(xí)到的內(nèi)容,大家可以在學(xué)完相關(guān)知識后再來看這個總結(jié)列表在struts.xml文件的<result>元素中,經(jīng)常需要使用${屬性名}表達(dá)式訪問action中的屬性,表達(dá)式里的屬性名對應(yīng)action中的屬性。如下:<result
type="redirect">view.jsp?id=${id}</result>在校驗配置文件的<message>元素中,可能需要使用${getText(‘key’)}表達(dá)式訪問國際資源包的消息。在國際化資源文件中,也可以使用${ognl表達(dá)式},例如,使用${getText(‘key’)}表達(dá)式來獲取國際化消息填充另一個資源的占位符。在jsp頁面中可以使用${獲取屬性的ognl表達(dá)式},但不能在${}使用調(diào)用方法的ognl表達(dá)式,否則,會把它當(dāng)作el表達(dá)式的自定義函數(shù)。國際化的基礎(chǔ)知識北京傳智播客教育配置全局的缺省國際化資源文件,在任意一個JSP頁面中用<s:textname=“”>、<s:property
value=“%{getText()}”>和帶有key屬性的各種標(biāo)簽來測試一下,并結(jié)合<s:text>標(biāo)簽的源碼和<s:debug>標(biāo)簽的查看結(jié)果來說明國際化顯示的原理。如果在資源包中沒有找到某個key對應(yīng)信息內(nèi)容,將直接輸出該key。增加以ActionClassName為基準(zhǔn)名稱資源包,并讓Action繼承
ActionSupport類,分析直接訪問jsp頁面時無法獲取ActionClassName資源包中的信息,而經(jīng)過該Action訪問時則可以獲得的原因。增加java包范圍下的資源包,對于有多級包名的情況,
perties文件放在哪一級包名下都是可以的。Struts2提供這么多種資源包方式,是不是太過了呢?No!模塊化管理思想!在Action類的源代碼中用ActionSupport類的getText方法獲取國際化資源消息。用<s:i18n>標(biāo)簽來明確指明從哪個資源包中獲取信息。在<s:text>標(biāo)簽和getText()方法中如何為占位符填充參數(shù)。<s:param
name=“名稱不重要”value=“ognl
expression”/><s:param>normal
text</s:param>國際化的高級應(yīng)用北京傳智播客教育支持國際化的應(yīng)用軟件應(yīng)該提供用戶選擇自己期望的本地信息的操作途徑。服務(wù)器端通過什么方式來記住用戶選擇的本地信息呢?服務(wù)器端通過什么方式來判斷用戶的Locale?Struts2通過i18n攔截器來自動實現(xiàn)幫助實現(xiàn)用戶選擇
locale的功能。I18n攔截器取request_locale的請求參數(shù)表示的locale并存儲進(jìn)Session,還取Session中的Locale填充ActionContext的Locale。為用戶提供選擇國際化的操作界面先完成簡單的再完成高級的MVC模式的回顧用戶請求Web容器ServletJavaBeanjsp北京傳智播客教育struts2的案例實踐北京傳智播客教育步驟:1.進(jìn)行簡要的需求分析與設(shè)計(見下頁)2.編寫出各個部件(一個有兩個業(yè)務(wù)方法的Action類和兩個jsp頁面)3.在struts.xml配置文件中配置各個組件4.在各個組件中編寫代碼把流程連接起來。注冊用例的簡要設(shè)計圖RegUserUIReguser.jspRegUser北京傳智播客教育Main.jsp<s:url>與<s:a>標(biāo)簽北京傳智播客教育<s:url>和<s:a>標(biāo)簽的四個好處:使用<s:url
action=“”namespace=“”method=“”/>不用關(guān)心web應(yīng)用程序的路徑和
Action映射的擴(kuò)展名。<s:url>中沒有指定namespace屬性時,將根據(jù)瀏覽器當(dāng)前所訪問的url地址來推測包名,并與action屬性指定的內(nèi)容一起生成最終的url地址。可以自動附加jsessionid參數(shù)進(jìn)行url重寫。可以對參數(shù)信息進(jìn)行url編碼。備注:jstl中的<c:url>標(biāo)準(zhǔn)標(biāo)簽也有<s:url>標(biāo)簽的后兩個作用。直接使用<s:url/>標(biāo)簽可以獲得當(dāng)前地址,只有使用includeParams屬性才會帶上原來的請求參數(shù)。大型網(wǎng)站的鏈接地址總是要帶上userid之類的信息。實驗步驟:啟動一個新瀏覽器訪問第一個Action,查看<s:url>生成的超鏈接地址,刷新訪問,再查看<s:url>生成的超鏈接地址,比較差異說明<s:url>標(biāo)簽的url重寫功能。在<s:url>的action屬性值的路徑后也可以直接加參數(shù),但不能對其中的中文進(jìn)行編碼。使用<s:param>子標(biāo)簽設(shè)置一個或多個參數(shù),可以完成中文參數(shù)的url編碼。再寫一個<s:url>標(biāo)簽,其中不帶任何屬性,并在訪問地址中增加一些參數(shù),查看其生成的url地址;接著設(shè)置其includeParams屬性,再查看結(jié)果。這里應(yīng)該打開標(biāo)簽的幫助文檔進(jìn)行講解。為上面的<s:url>標(biāo)簽增加var屬性,并用<s:property>標(biāo)簽輸出var屬性指定的變量。問題:使用s:url>標(biāo)簽的value屬性時,其中的值不會當(dāng)作OGNL表達(dá)式處理,而是當(dāng)作普通字符串處理,如果value的內(nèi)容要根據(jù)表達(dá)式運算,如何做?在value屬性值中使用%{},struts2就會把其中內(nèi)容當(dāng)作ognl表達(dá)式處理。接受請求參數(shù)北京傳智播客教育步驟:1.在網(wǎng)頁中添加原始的<form>標(biāo)簽、三個輸入框(包括用戶名、密碼和確認(rèn)密碼)和一個提交按鈕。password2采用基本屬性,用戶名和密碼采用
和user.password的復(fù)合形式。2.由提交路徑編寫不方便引入<s:form>的應(yīng)用。3.在Action中增加基本屬性和user實體對象,在業(yè)務(wù)方法中打印結(jié)果數(shù)據(jù)和在jsp頁面中使用<s:property>顯示結(jié)果數(shù)據(jù)。4.
分析user實體對象在定義時被初始化和未被初始化的運行區(qū)別。5.分析params攔截器將請求參數(shù)填充進(jìn)Action屬性中的源代碼。6.將請求參數(shù)封裝到由ModelDriven接口提供的模型對象中。總結(jié):Struts框架在把請求交給action的業(yè)務(wù)方法去處理之前,可以將請求參數(shù)來填充到Action的相應(yīng)屬性中,所以,對于請求消息中的每個參數(shù)(包括網(wǎng)頁表
單中的每個字段),Action中通常都有一個對應(yīng)的屬性來接受相應(yīng)的參數(shù)值。在action的業(yè)務(wù)方法中也可以訪問ServletAPI,通過request.getParameter獲得參數(shù),但這違背了使用框架的精神。在url路徑中附帶請求參數(shù)北京傳智播客教育Action的配置元素下可以用<param>子元素為其注入屬性,這是由于
StaticParametersInterceptor
的作用效果。Struts2支持在路徑中附帶請求參數(shù)的方式,例如/course/create/1中的1可以用于表示某個請求參數(shù)的值,為此需要做三件事:用*通配符映射Action的路徑,例如,<actionname=“course/*”>用<param>子元素將*匹配的結(jié)果注入給Action的某個屬性,例如,<param
name=“id”>{1}</param>設(shè)置常量struts.enable.SlashesInActionNames和struts.mapper.alwaysSelectFullNamespace。分階段的表單提交下一步第1個頁面北京傳智播客教育第2個頁面FormBean顯示模型數(shù)據(jù)在jsp頁面中可以直接使用<s:property>標(biāo)簽來顯示Action實例對象上的屬性,這是因為當(dāng)前Action實例對象會被存儲進(jìn)ValueStack的CompoundRoot中,而
ValueStack又被存在request作用中,這相當(dāng)于模型數(shù)據(jù)最終被間接地存儲進(jìn)
request作用域中。其原理如下圖所示:可以用el表達(dá)式顯示Action中的屬性值,這是為什么呢?打印request對象的類名,它是struts2提供的一個HttpServletRequest的包裝類,這個包裝的request對象的getAttribute方法除了找自己的attribute集合,還去ValueStack,即可以從ValueStack中的各個對象上獲取屬性。當(dāng)前的Action又是放在ValueStack的棧頂上的,所以,在jsp頁面中也可以使用${}來獲得Action的屬性。查看StrutsRequestWrapper的源碼,可以驗證上面這個思路。結(jié)論:要提供給JSP頁面顯示用的模型數(shù)據(jù),作為Action的屬性提供即可被JSP頁面訪問。北京傳智播客教育Redirect
After
Post模式RegUserUIRegUser.jspRegUserList.jspValidate
errorList.jspListActionRedirect解決刷新問題forward北京傳智播客教育表單校驗北京傳智播客教育如果Action實現(xiàn)了Validatable接口和其Validate方法,Validation攔截器在調(diào)用
Action的業(yè)務(wù)方法之前,可以調(diào)用Action中的validate方法進(jìn)行數(shù)據(jù)進(jìn)行校驗,編寫完校驗方法后,根據(jù)運行的錯誤提示信息,引入名稱為input的result的講解。不管校驗成功與否,Validation攔截器都將繼續(xù)放行。后續(xù)的Workflow攔截器判斷Action身上是否有校驗錯誤,沒有則調(diào)用Action的業(yè)務(wù)方法,否則,它將返回一個錯誤頁面。.分析校驗出錯回到剛才填寫表單信息的輸入頁面后該怎么辦?要在該頁面中顯示出上次填入的內(nèi)容和錯誤提示信息,并要在Action內(nèi)部提前將錯誤消息國際化。先用<s:fieldError>標(biāo)簽顯示出所有錯誤消息,再用<s:fieldErrorfieldName=“”>標(biāo)簽顯示某個字段的錯誤。最后用普通el表達(dá)式提取數(shù)據(jù)回顯和用<s:property>標(biāo)簽結(jié)合ognl表達(dá)式顯示錯誤信息,以克服<s:fieldError>的顯示缺陷。fieldErrors內(nèi)部的數(shù)據(jù)結(jié)構(gòu)圖見下頁。演示validate方法對Action內(nèi)所有請求處理方法都產(chǎn)生了作用,可以采用
@SkipValiation注解,讓struts2框架對Action中的某個業(yè)務(wù)方法不調(diào)用校驗方法;也可以編寫validateXxx方法,只對xxx方法進(jìn)行校驗。采用一種簡單方式來控制表單數(shù)據(jù)的回顯和校驗錯誤信息的顯示:即采用Struts2的表單元素標(biāo)簽自動回顯數(shù)據(jù)和錯誤消息,用simple主題控制表單元素的顯示結(jié)果,再用<s:property>標(biāo)簽結(jié)合ognl表達(dá)式顯示錯誤信息。FieldErrors的存儲結(jié)構(gòu)FieldErrors北京傳智播客教育國際化后的表示錯誤的字符串field1國際化后的表示錯誤的字符串國際化后的表示錯誤的字符串field2
國際化后的表示錯誤的字符串國際化后的表示錯誤的字符串field3國際化后的表示錯誤的字符串國際化后的表示錯誤的字符串采用配置文件進(jìn)行表單校驗北京傳智播客教育采用配置文件校驗方式雖然不需要Action實現(xiàn)Validatable接口,但Action必須實現(xiàn)ValidationAware,即還是要繼承ActionSupport。采用配置文件進(jìn)行校驗,先參照寫struts2自帶的blank例子編寫ActionClassName-validation.xml文件,看到它對所有方法都產(chǎn)生了作用,不想對顯示表單的請求方法進(jìn)行校驗,則只編寫針對某個方法的ActionClassName-actionname-validation.xml
。另外,在處理請求
方法上使用@SkipValiation注解,配置文件校驗方式也將無效。采用配置文件校驗方式校驗后,Action中的validatable有關(guān)的校驗方法也會執(zhí)行,且配置文件校驗方式在validate校驗方法之前執(zhí)行。參照文檔了解與一下校驗器短路的有關(guān)情況:配置每個普通校驗器和字段校驗器都可以設(shè)置一個short-circuit屬性同一種類型的校驗器,排在前面的可以短路排在后面的校驗器普通校驗器總是先于字段校驗器執(zhí)行,所以字段校驗器不能短路普通校驗器參照文檔了解如何注冊自己的校驗器,一旦注冊了自己的校驗器,xwork中原來默認(rèn)注冊的校驗器都需要重新注冊。對錯誤提示信息進(jìn)行國際化處理通過<message>元素的key屬性在<message>標(biāo)簽體內(nèi)部使用ognl表達(dá)式和getText方法。實現(xiàn)客戶端校驗和用<s:head>標(biāo)簽引入控制校驗失敗提示信息的css文件注意:每個表單元素必須用struts自己的標(biāo)簽還可以用注解方式配置校驗規(guī)則和用@InputConfig指定input視圖。用戶注冊案例的實驗——增加用戶名已存在的業(yè)務(wù)校驗北京傳智播客教育表單校驗錯誤和業(yè)務(wù)邏輯校驗錯誤的處理流程:表單校驗:請求參數(shù)-->Action-->Action.validate-->表單校驗錯誤則返回errors-->reguserUI.jsp-->顯示出錯誤信息業(yè)務(wù)邏輯校驗:請求參數(shù)-->Action-->Action.validate-->表單校驗成功則調(diào)用Action.execute方法-->邏輯校驗錯誤-->產(chǎn)生errors-->回reguser.jsp顯示錯誤信息步驟:1.在Action中增加用戶名已存在則回到輸入頁面并能顯示出錯誤提示信息的代碼。(假設(shè)用戶名為zxx時即表示已存在)2.實現(xiàn)錯誤提示信息的國際化,提示信息中要用一個參數(shù)來替代字段名,即參數(shù)化。3.將提示信息的參數(shù)值改為也從資源文件中獲取,并且也是可國際化的,即參數(shù)的國際化。FreeMarker北京傳智播客教育看freemarker的文檔,了解相關(guān)知識:在文檔首頁上就有一幅template+model=output的圖參看Template
Author's
Guide的Getting
Started介紹模板參看Programmer‘sGuide的GettingStarted編寫合并模板文件與模型的HelloWorld例子。比較FreeMarker與JSP(在faq部分就有說明),接著再將先前的FreeMarker例子代碼抽取成方法后應(yīng)用到Servlet中。模板文件結(jié)構(gòu):指令與自定義指令、插值、表達(dá)式(包括built-ins和自定義函數(shù)/方法)Freemarker的數(shù)據(jù)模型中的數(shù)據(jù)類型還包括自定義指令和自定義函數(shù),見Template
Author‘s
Guide>Values,Types>The
types。在
Programmer‘s
Guide>The
Data
Model
可以看到自定義指令和自定義方法的有關(guān)講解。Freemarker的配置與模板加載,見Programmer‘s
Guide>TheConfiguration。Programmer‘s
Guide>Miscellaneous>Using
FreeMarker
withservlets部分講了了如何整合jsp的自定義標(biāo)簽庫。FreeMarker在Struts2中應(yīng)用北京傳智播客教育用FreeMarker作為Struts2的視圖:看Struts2的FreeMarkerResult類的源碼,可以從webapp和classpath環(huán)境中加載ftl文件。看FreeMarkerResult的幫助頁,其中FreemarkerSupport
的超鏈接目標(biāo)頁面介紹了初始的內(nèi)置對象變量和屬性訪問范圍。UI組件的模板定制:模板與主題分析Struts2在FreeMarker的數(shù)據(jù)模型中設(shè)置的內(nèi)置對象變量和修改屬性訪問范圍的源碼。修改ftl模板將struts2的UI標(biāo)簽顯示的錯誤消息放置到UI元件的左邊。修改ftl模板將struts2的UI標(biāo)簽的required屬性改為“必須”,并進(jìn)行國際化定制。用戶注冊案例的實驗北京傳智播客教育——簡單UI標(biāo)簽的應(yīng)用步驟:1.體驗<s:textfield>標(biāo)簽生成用戶名輸入框字段時的
cssErrorClass、labelSeparator、required和requiredPosition等屬性。2.使用<s:password>標(biāo)簽生成密碼和確認(rèn)密碼輸入框字段,注意其showPassword屬性。3.使用<s:submit>標(biāo)簽的action屬性實現(xiàn)一個表單下的多個提交按鈕分別提交給不同的路徑或方法。4.使用<s:checkbox>標(biāo)簽創(chuàng)建出“婚否”復(fù)選框,以及CheckBoxInterceptor攔截的原理。將請求參數(shù)轉(zhuǎn)換成整數(shù)與日期類型北京傳智播客教育步驟:1.由注冊頁面中的int類型的height字段在struts2里面有0顯示的問題,引出基本數(shù)據(jù)類型最好采用其對應(yīng)的包裝類型進(jìn)行定義。另外,<s:textfield>標(biāo)簽在轉(zhuǎn)換出錯時還會自動將不合法的數(shù)據(jù)重新顯示出來。2.在action中增加java.util.Date類型的birthday屬性和在jsp頁面中增加對應(yīng)的<s:textfield>標(biāo)簽。在value屬性中使用<s:date>進(jìn)行格式化還原,或者不讓用戶鍵盤輸入,只讓用戶通過日歷控件選擇。3.struts2中的UI標(biāo)簽的value屬性中的內(nèi)容默認(rèn)都不是當(dāng)作
ognl表達(dá)式處理,而是當(dāng)作普通字串看待,為了用ognl表達(dá)式,需要加%{}。如果某個屬性中的內(nèi)容默認(rèn)當(dāng)作ognl表示來用,而你就是想給它一個原始字符串,也可以用%{}進(jìn)行解決,例如,value=“%{‘haha’}”優(yōu)于value=“’haha’”。用戶注冊案例的實驗——增加一組復(fù)選框北京傳智播客教育步驟:1.用原始的html標(biāo)簽在網(wǎng)頁中寫出復(fù)選框列表,屬性名稱為
specialities;使用<s:checkboxlist>完成復(fù)選框列表的自動生成和自動填充復(fù)選框內(nèi)容。2.在action中定義接受復(fù)選框參數(shù)的數(shù)組屬性,并在action中打印出數(shù)組結(jié)果;3.由表單校驗出錯后回到輸入jsp頁面無法正常顯示復(fù)選框列表,引出action元素的input屬性配置問題和chain視圖;4.分析chain視圖的問題與WorkflowInterceptor攔截器的作用。5.將水平排列的復(fù)選框列表改為垂直排列的復(fù)選框形式。結(jié)合enum技術(shù)增加一組單選按鈕北京傳智播客教育需求:用性別引出生成一組單選按鈕的講解,性別用一個枚舉類型表示。步驟:1.編寫枚舉類Gender的成員,暫不在枚舉中引入方法。2.借鑒講解國際化時使用<s:select>標(biāo)簽的分析思路,分析一組單選按鈕的html源碼和用<s:radio>標(biāo)簽渲染出一組單選按鈕的原理,從而引出在Gender枚舉類中增加額外方法的問題以及對單選按鈕的標(biāo)題進(jìn)行國際化處理。只要把<s:radio>標(biāo)簽的名字改為<s:select>,其他什么都不動,就可以變成下拉列表框了。3.在user中定義Gender成員變量,提交表單后可以看到struts2能夠自動將請求參數(shù)轉(zhuǎn)換成Gender類型,不需要編寫枚舉類的類型轉(zhuǎn)換器。Struts2中的其他UI標(biāo)簽北京傳智播客教育<s:optgroup>標(biāo)簽<bobox>標(biāo)簽<s:doubleselect>標(biāo)簽<s:optiontransferselect>標(biāo)簽集合類型的屬性處理北京傳智播客教育對于多個采用相同復(fù)合名稱(如user.phone)的表單元素,它們在后臺可以用非數(shù)組屬性中的數(shù)組屬性(如user.phone[])表示,也可以用數(shù)組屬性中的非數(shù)組屬性(如person[].phone
)表示:對于后者,不能使用數(shù)組類型,而必須使用List泛型集合的方式,即List<Person>這種泛型類型。因為數(shù)組元素的類型無法通過反射得到,而將請求參數(shù)賦值給模型時需要進(jìn)行類型轉(zhuǎn)換,即必須要知道轉(zhuǎn)換的目標(biāo)數(shù)據(jù)的類型。在jsp頁面中采用索引號方式指定元素在集合中的順序位置:非索引號方式不能單獨回顯各個表單元素中的數(shù)據(jù),采用索引號方式能夠回顯各個表單元素中的數(shù)據(jù),例如,提交出錯時,各個文本框顯示各自的原始內(nèi)容。對索引號的方式,數(shù)組元素要求必須先創(chuàng)建出數(shù)組對象,而使用List集合不用。Map集合的應(yīng)用與采用索引號的數(shù)組集合屬性的功能類似,能夠回顯各個表單元素中的數(shù)據(jù)。如果多個集合中采用相同的key,可以將多個集合中的每個元素分別關(guān)聯(lián)起來,參看itcastbbs多附件上傳的效果演示。轉(zhuǎn)換器北京傳智播客教育Struts2的轉(zhuǎn)換器負(fù)責(zé)完成雙向轉(zhuǎn)換功能將字符串?dāng)?shù)組類型的請求參數(shù)轉(zhuǎn)換成Java對象將Java對象轉(zhuǎn)換成字符串在web頁面中顯示
一個bug:如果要轉(zhuǎn)換的對象是Action的某個屬性對象中的屬性,這時候?qū)⒄{(diào)用要轉(zhuǎn)換的對象的toString方法,而不是調(diào)用轉(zhuǎn)換器。Struts2轉(zhuǎn)換器要實現(xiàn)TypeConverter接口,或者繼承DefaultTypeConverter和StrutsTypeConverter兩個類中的一個。轉(zhuǎn)換器的注冊:局部轉(zhuǎn)換器:ActionClassNperties文件全局轉(zhuǎn)換器:perties文件JavaBea
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 設(shè)計公司晉升管理制度
- 設(shè)計裝修公司管理制度
- 診所職工健康管理制度
- 試制車間安全管理制度
- 財務(wù)銷售倉庫管理制度
- 財富公司運營管理制度
- 貨代公司安全管理制度
- 貨物現(xiàn)場包裝管理制度
- 貨站疫情防控管理制度
- 2025年中國定制首飾行業(yè)市場全景分析及前景機遇研判報告
- 2023年河北石家莊市市屬國有企業(yè)面向社會招聘筆試參考題庫附帶答案詳解
- 醫(yī)學(xué)高級職稱正高《中醫(yī)內(nèi)科學(xué)》(題庫)模擬試卷四
- 食品機械及設(shè)備課程設(shè)計報告
- 信邦益心舒膠囊課件
- 疼痛的藥物治療及術(shù)后鎮(zhèn)痛
- 南海區(qū)2021-2022英語期末考試八年級答案
- YY 9706.241-2020醫(yī)用電氣設(shè)備第2-41部分:手術(shù)無影燈和診斷用照明燈的基本安全和基本性能專用要求
- YB/T 036.19-1992冶金設(shè)備制造通用技術(shù)條件涂裝
- GB/T 27024-2014合格評定人員認(rèn)證機構(gòu)通用要求
- 1:1000地形圖測繪項目技術(shù)設(shè)計書
- 2023年教師職稱考試題
評論
0/150
提交評論