1, 當(dāng)Action設(shè)置了某個(gè)屬性后,Struts將這些屬性封裝一個(gè)叫做Struts.valueStack的屬性里。獲取valueStack對(duì)象: ValueStack vs = (ValueStack) request.getAttribute("struts.valueStack"); 調(diào)用ValueStack 的vs.findValue("books")方法(books為Action中的屬性); 2, struts2的Action類(lèi)是一個(gè)普通的POJO類(lèi)(通常包含一個(gè)無(wú)參的execute方法)從而很 好的重用代碼。 4,struts2通常直接使用Action來(lái)封裝HTTP請(qǐng)求參數(shù),所以Action中要定義與請(qǐng)求參數(shù)對(duì)應(yīng)的屬性,并且為該屬性提供相應(yīng)的 getter和setter方法。 5,即使Action需要處理的請(qǐng)求name和pass兩個(gè)HTTP請(qǐng)求參數(shù),Action類(lèi)也可以不包含name和pass屬性,因?yàn)橄到y(tǒng)是通過(guò)對(duì)應(yīng)的 getter和setter方法來(lái)處理請(qǐng)求參數(shù)。而不是通過(guò)屬性來(lái)處理請(qǐng)求參數(shù)的。所以Action類(lèi)是否包含name和pass屬性不重要, 重要的是需要setter和getter方法。 6,Action類(lèi)的屬性,不僅可以封裝請(qǐng)求參數(shù),還可以用于封裝處理結(jié)果,通過(guò)Struts2標(biāo)簽來(lái)輸出對(duì)應(yīng)的屬性值。如 <s:Property value="tip">。 7,ActionContext類(lèi)。Struts2的Action并未直接與任何Servlet api耦合,從而更加方便測(cè)試該Action(可以通過(guò)脫離web容器測(cè)試Action)。但是對(duì)于Web應(yīng)用的控制器來(lái)說(shuō),不訪問(wèn)Servlet api 幾乎是不能的。例如跟蹤HTTP session狀態(tài)等。訪問(wèn)的Servlet Api 就 是HttpServeltRequest、HttpSession、ServletContext,這三個(gè)類(lèi)分別jsp內(nèi)置對(duì)象中的request、session、application。Web應(yīng)用中提供了一個(gè)ActionContext類(lèi),Struts2的Action可以通過(guò)該類(lèi)來(lái)訪問(wèn)Servlet api。 該類(lèi)的ActionContext提供getContext方法得到ActionContext實(shí)例, 該類(lèi)的方法: ①Object get(Object key),該方法類(lèi)似于HttpServletRequest的getAttribute(String name)方法; ②Map getApplication(),返回Map對(duì)象,該對(duì)象模擬了應(yīng)用的ServletContext的實(shí)例 ③static ActionContext getContext(),靜態(tài)方法,獲得系統(tǒng)提供的ActionContext實(shí)例。 ④Map getParameters()獲取所有的請(qǐng)求參數(shù),類(lèi)似于調(diào)用HttpServletRequest對(duì)象的getParammeterMap方法。 ⑤Map getSession()該Map對(duì)象模擬了HttpSession實(shí)例。 ⑥void setApplication(Map application)直接傳入一個(gè)Map實(shí)例,將該Map實(shí)例的key-value對(duì)轉(zhuǎn)換成application的屬性名、屬性值。類(lèi)似的還有setSession(Map session) ⑦put(Object key, Object value)直接為HttpServletRequest設(shè)置屬性。相當(dāng)于request.setAttribute(key,value).可通過(guò)EL表達(dá)式輸出。 8,ServletActionContext類(lèi)(是ActionContext類(lèi)的子類(lèi))。 雖然Struts2提供了ActionContext來(lái)訪問(wèn)Servlet Api,但是這種訪問(wèn)畢竟不能直接獲得Servlet Api實(shí)例,為了Action中 直接訪問(wèn)Servlet api,Struts2提供了如下的接口:ServletContextAware、ServletRequestAware、ServletResponseAware 。如果Action實(shí)現(xiàn)這些接口,能分別直接訪問(wèn)用戶請(qǐng)求的ServletContext、HttpServletRequest、HttpServletResponse實(shí)例。 并且,為了直接訪問(wèn)Servlet api。Struts2提供了一個(gè)ServletAction類(lèi)。通過(guò)ServletActionContext類(lèi)可以更加方便的地直接訪問(wèn)Servlet api。這類(lèi)的主要方法(全是static): ①getActionContext(HttpServletRequest req)得到當(dāng)前的ActionContext實(shí)例。 ②getActionMapping()得到ActionMapping實(shí)例(得到 action mapping為context)。 ③getRequest()得到HttpServletRequest實(shí)例(Gets the HTTP servlet request object)。 ④getResponse()得到HttpServletResponse實(shí)例(Gets the HTTP servlet response object.) ⑤getServletContext()得到ServletAction實(shí)例(Gets the servlet context.) ⑥getValueStack(HttpServletRequest req)得到ValueStack實(shí)例。 ⑦setRequest(HttpServletRequest request)(Sets the HTTP servlet request object)相應(yīng)的有setResponse(HttpServletResponse response)、setServletContext(ServletContext servletContext)。 9,雖然可以在Action類(lèi)獲取HttpServletResponse,但如果希望通過(guò)HttpServletResponse來(lái)生成服務(wù)器響應(yīng)是不可能的,因?yàn)锳ction只是控制器(它并不直接對(duì)瀏覽器生成任何相應(yīng))。即如果在Action中寫(xiě)如下代碼:response.getWriter().println("hello world"); 是沒(méi)有意義的。 10,對(duì)于使用Struts2框架的應(yīng)用而言,盡量不要讓超級(jí)鏈接鏈接到某個(gè)視圖資源, 因?yàn)檫@種方式增加了額外的風(fēng)險(xiǎn),推薦將所有請(qǐng)求都發(fā)給Struts2框架,讓該框架來(lái)處理用戶的請(qǐng)求, 即使是簡(jiǎn)單的超級(jí)鏈接。 11,邏輯視圖名是指:Action返回的字符串;物理視圖是指:頁(yè)面的實(shí)際名稱。 Struts2通過(guò)配置邏輯視圖名和物理視圖之間的映射關(guān)系,一旦系統(tǒng)收到Action返回的某個(gè)邏輯視圖,系統(tǒng)就會(huì)把相應(yīng)的物理視圖呈現(xiàn)給用戶。 12,默認(rèn)值:如果配置<result../>元素時(shí)沒(méi)有指定location參數(shù),系統(tǒng)將會(huì)把<result..>...<result../>中間的字符串當(dāng)成實(shí)際視圖資源。如果沒(méi)有配置parse參數(shù),則默認(rèn)值為true(該參數(shù)指定實(shí)際視圖名是否可以使用OGNL表達(dá)式);如果沒(méi)有指定name屬性則默認(rèn)值為Struts2的默認(rèn)處理結(jié)果類(lèi)型(dispacher). 13,歸納起來(lái),Struts2內(nèi)建支持結(jié)果類(lèi)型如下(14): ①chain結(jié)果類(lèi)型:Action鏈?zhǔn)教幚斫Y(jié)果類(lèi)型。 ②chart結(jié)果類(lèi)型:用于整合JFreeChart的結(jié)果類(lèi)型。 ③dispatch結(jié)果類(lèi)型:用于jsp整合的結(jié)果類(lèi)型。 ④freemarker結(jié)果類(lèi)型:FreeaMarker整合的結(jié)果類(lèi)型。 ⑤httpheader結(jié)果類(lèi)型:用于控制Http行為的結(jié)果類(lèi)型。 ⑥jasper結(jié)果類(lèi)型:用于JasperReports整合的結(jié)果類(lèi)型。 ⑦jsf結(jié)果類(lèi)型:用于整合JSF整合的結(jié)果類(lèi)型。 ⑧redirect結(jié)果類(lèi)型:用于直接跳轉(zhuǎn)到其他的URI的結(jié)果類(lèi)型。 ⑨redirectAction結(jié)果類(lèi)型:用于直接跳轉(zhuǎn)到其他的Action的結(jié)果類(lèi)型。 ⑩stream結(jié)果類(lèi)型:用于向?yàn)g覽器返回一個(gè)InputStream(一般用于文件下載)。 ⑾tiles結(jié)果類(lèi)型:用于與Tiles整合的結(jié)果類(lèi)型。 ⑿velocity結(jié)果類(lèi)型:用于與Velocity整合的結(jié)果類(lèi)型。 ⒀xslt結(jié)果類(lèi)型:用于與XML/XSLT整合的結(jié)果類(lèi)型。 ⒁plainText結(jié)果類(lèi)型:用于顯示某個(gè)頁(yè)面的原始代碼的結(jié)果類(lèi)型。 14,【redirect】結(jié)果類(lèi)型。 這種結(jié)果類(lèi)型與dispatch結(jié)果類(lèi)型相對(duì),dispatch結(jié)果類(lèi)型是將請(qǐng)求Forward(轉(zhuǎn)發(fā)) 到指定的jsp資源。而redirect結(jié)果類(lèi)型,則意味著將請(qǐng)求Redirect(重定向) 到指定的視圖資源。 dispatch結(jié)果類(lèi)型與redirect結(jié)果類(lèi)型的差別就是轉(zhuǎn)發(fā)和重定向的差別: 重定向會(huì)丟失所有的請(qǐng)求參數(shù)和請(qǐng)求屬性---當(dāng)然也會(huì)丟失Action的處理結(jié)果。 使用redirect結(jié)果類(lèi)型的效果是:系統(tǒng)將調(diào)用HttpServletResponse的sendRedirect(String)方法來(lái)重定向指定的視圖資源,這種重定向的效果就是重新產(chǎn)生一個(gè)請(qǐng)求。所以所有的請(qǐng)求參數(shù)、請(qǐng)求屬性、Action實(shí)例和Action中封裝的屬性全部丟失。 15,【redirectAction】結(jié)果類(lèi)型. 使用redirectAction結(jié)果類(lèi)型時(shí),系統(tǒng)將重新生成一個(gè)新的請(qǐng)求, 只是該請(qǐng)求的URI不是一個(gè)具體的試圖資源,而是一個(gè)Action。因此前一個(gè)Action處理結(jié)果 ,請(qǐng)求參數(shù),請(qǐng)求參數(shù)都會(huì)丟失。 16,除了可以通過(guò)通配符來(lái)配置Action(result),還可以使用OGNL表達(dá)式,這種 用法允許讓請(qǐng)求參數(shù)來(lái)決定結(jié)果。如: <action name="save" class="......." method="save"> <result name="input">/..jsp</result> <result type="redirect" >edit.action?skillName=${currentSkill.name}</result> </action> 對(duì)于上面的表達(dá)式語(yǔ)法,要求對(duì)應(yīng)的Action實(shí)例里應(yīng)該包含currentSkill屬性,且currentSkill屬性必須包含name屬性--否則,${currentSkill.name}表達(dá)式為null。 17,模型驅(qū)動(dòng): 對(duì)于Struts1的ActionForm對(duì)象而言。它的唯一作用就是封裝請(qǐng)求參數(shù),當(dāng)Struts1攔截到用戶的請(qǐng)求后,Struts1負(fù)責(zé)將請(qǐng)求參數(shù)封裝成ActionForm對(duì)象。 如果Struts2的開(kāi)發(fā)者懷念這種開(kāi)發(fā)方式,則可以使用Struts2提供的模型驅(qū)動(dòng)模式, 這種模式也通過(guò)專(zhuān)門(mén)的JavaBean來(lái)封裝請(qǐng)求參數(shù)。 相比于Struts1的Action類(lèi),Struts2的Action承擔(dān)了太多的責(zé)任,既用于封裝來(lái)回請(qǐng)求的參數(shù),也保護(hù)了控制邏輯---這種模式實(shí)在不太清晰。出于清晰的考慮,應(yīng)該采用單獨(dú)的Model實(shí)例來(lái)封裝請(qǐng)求參數(shù)和處理結(jié)果,這就是所謂的模型驅(qū)動(dòng)。 作用:Struts2的模型對(duì)象可以封裝更多的信息,它不僅可以封裝用戶的請(qǐng)求參數(shù),而且還可以封裝Action的處理結(jié)果。用單獨(dú)的JavaBean實(shí)例來(lái)貫穿MVC流程。 使用模型驅(qū)動(dòng)時(shí),Action必須實(shí)現(xiàn)ModelDriven接口,且必須實(shí)現(xiàn)getModel方法, 該方法用于把Action和與之相對(duì)應(yīng)的Model實(shí)例關(guān)聯(lián)起來(lái)。 簡(jiǎn)單的說(shuō),模型驅(qū)動(dòng)使用單獨(dú)的VO(值對(duì)象)來(lái)封裝請(qǐng)求參數(shù)和處理結(jié)果。 18,【屬性驅(qū)動(dòng)】: 使用屬性(Property)作為貫穿MVC流程的信息攜帶者,當(dāng)然屬性無(wú)法獨(dú)立存在,他必須依附于一個(gè)對(duì)象,這個(gè)對(duì)象就是Action實(shí)例, 簡(jiǎn)單的說(shuō),屬性驅(qū)動(dòng)使用Action實(shí)例來(lái)封裝請(qǐng)求參數(shù)和處理結(jié)果。 19,Struts2的【處理異常機(jī)制】: 在execute方法中手動(dòng)捕捉異常,當(dāng)捕捉到特定的異常時(shí),返回特定的視圖--但是 這種方式很是繁瑣,需要在execute中書(shū)寫(xiě)大量的catch塊,最大的缺點(diǎn) 還在于異常與代碼耦合,一旦需要改變異常處理方式,必須修改代碼! Struts2提供了一種聲明式的異常處理方式。 在輸出錯(cuò)誤信息的jsp頁(yè)面,有兩種輸出方式: ①通過(guò)struts2標(biāo)簽輸出異常對(duì)象的message屬性。<s:property value="exception.message"/>。 ②通過(guò)struts2標(biāo)簽輸出堆棧信息。<s:property value="exceptionStack"/>。 注意:全局異常映射的result屬性通常不要使用局部結(jié)果,局部異常映射的result屬性可以使用全局結(jié)果,也可以不使用。 20,對(duì)于WEB應(yīng)用而言,所有的請(qǐng)求參數(shù)都是字符串類(lèi)型的。 21,【類(lèi)型轉(zhuǎn)換器】: struts2的類(lèi)型轉(zhuǎn)換器實(shí)際上是基于OGNL實(shí)現(xiàn)的,在OGNL項(xiàng)目中有一個(gè)TypeConverter接口,因其實(shí)現(xiàn)的方法過(guò)于麻煩,所以O(shè)GNL項(xiàng)目還提供了一個(gè)該接口的實(shí)現(xiàn)類(lèi):DefaultTypeConverter,通過(guò)繼承該類(lèi)來(lái)實(shí)現(xiàn)自己的轉(zhuǎn)換器。 實(shí)現(xiàn)自定義的類(lèi)型轉(zhuǎn)換需要重寫(xiě)DefaultTypeConverter類(lèi)的convertValue方法。 22,上面的類(lèi)型轉(zhuǎn)換器都是基于OGNL的DefaultTypeConverter類(lèi)實(shí)現(xiàn)的,基于 該類(lèi)實(shí)現(xiàn)類(lèi)型轉(zhuǎn)換器的時(shí)候時(shí),將字符串轉(zhuǎn)化成符合類(lèi)型要通過(guò)convertValue方法實(shí)現(xiàn) 因此我們必須先通過(guò)toType參數(shù)來(lái)判斷轉(zhuǎn)換的方向,然后分別實(shí)現(xiàn)不同的轉(zhuǎn)換邏輯。 為了簡(jiǎn)化類(lèi)型轉(zhuǎn)換的實(shí)現(xiàn),struts2提供了一個(gè)StrutsTypeConverter抽象類(lèi)(基于struts2的類(lèi)轉(zhuǎn)換器) 這個(gè)抽象類(lèi)是DefaultTypeConverter類(lèi)的子類(lèi). 23,對(duì)于以上的類(lèi)型轉(zhuǎn)換,我們一直只處理字符串?dāng)?shù)組的第一個(gè)元素---我們都假設(shè)請(qǐng)求參數(shù)是單個(gè)值。實(shí)際上,必須考慮請(qǐng)求參數(shù)是字符數(shù)組的情形, 假設(shè)用戶信息的請(qǐng)求參數(shù),名稱都是user。那么這兩個(gè)請(qǐng)求參數(shù)必須通過(guò)getParameterValues方法來(lái)獲取參數(shù)。此時(shí)user請(qǐng)求參數(shù)必須是數(shù)組類(lèi)型,或者List類(lèi)型(實(shí)際上,List和數(shù)組是完全相通的)。 24,因?yàn)閟truts2內(nèi)建的OGNL表達(dá)式的支持,那么可以用另一種方式將請(qǐng)求參數(shù)轉(zhuǎn)換成復(fù)合類(lèi)型,如(JSP頁(yè)面中): <input type=text name="user.name"/>,<input type=text name="user.pass"/>這樣就不需要轉(zhuǎn)換器了。 通過(guò)這種方式也可以把字符串轉(zhuǎn)換成復(fù)合類(lèi)型。但需要注意以下幾點(diǎn): ①因?yàn)閟truts2是需要直接創(chuàng)建一個(gè)復(fù)合類(lèi)(User類(lèi))的實(shí)例,因此系統(tǒng)必須為該復(fù)合類(lèi)構(gòu)建一個(gè)無(wú)參的構(gòu)造方法。 ②如果希望使用user.name請(qǐng)求參數(shù)的形式為Action實(shí)例的user屬性和pass屬性賦值,則必須為user屬性對(duì)應(yīng)的復(fù)合類(lèi)型提供setName方法,因?yàn)閟truts2是通過(guò)該方法類(lèi)為屬性賦值的。當(dāng)然Action類(lèi)還應(yīng)該包含setUser方法。 25,表單元素enctype屬性指定的是表單數(shù)據(jù)的編碼方式。屬性有如下3個(gè)值: ①application/x-www-form-urlencoded:這是默認(rèn)的編碼方式。它只處理表單中的value屬性值,采用這種編碼方式會(huì)將表單域的值處理成URL編碼方式。 ②multipart/form-data:這種編碼方式會(huì)以二進(jìn)制流的方式來(lái)處理表單數(shù)據(jù),這種編碼方式會(huì)把文件域指定的文件內(nèi)容也封裝到請(qǐng)求參數(shù)里。 ③text/plain:這種編碼方式當(dāng)表單的action的屬性為mailto:URL的形式時(shí)比較方便,這種方式主要適用于直接通過(guò)表單發(fā)送郵件的方式。 26,通過(guò)Action在jsp頁(yè)面輸出提示信息,我們可以 ①在Action中添加一個(gè)屬性(通過(guò)setXx方法設(shè)置屬性值),然后通過(guò)struts2的標(biāo)簽(<s:properties value="xx"/>)在jsp頁(yè)面輸出。 ②通過(guò)ActionContext類(lèi)來(lái)處理,如:ActionContext.getContext.put(key,value);然后通過(guò)EL表達(dá)式進(jìn)行輸出。 27,在Form表單中action屬性的值要得到【上下文路徑】: ①<%=request.getContextPath()%> ②還可以通過(guò)EL表達(dá)式得到 :${pageContext.request.contextPath} 28,得到【ValueStack】的對(duì)象有哪幾種方法: ①ServletActionContext類(lèi)中的方法:static getValueStack(HttpServletRequest req)【Gets the current value stack for this request】; ②ActionContext類(lèi)中的方法:getValueStack()【Gets the OGNL value stack.】; ③ValueStack vs = (ValueStack) request.getAttribute("struts.valueStack"); (request.getAttribute()返回一Object類(lèi)型) 29,【攔截器】。在默認(rèn)的情況下,如果我們?yōu)槟硞€(gè)Action定義了攔截器,則這個(gè)攔截器會(huì)攔截Action的所有方法??赡茉谟行┣闆r下,我們無(wú)需攔截器所有的方法,只需要攔截某些方法,此時(shí)就需要struts2攔截器的方法過(guò)濾特性。 30,struts2的【校驗(yàn)】,可以繼承ActionSupport類(lèi)重寫(xiě)validate方法,利用ActionSupport的addFieldError方法把錯(cuò)誤信息通過(guò)key保存起來(lái),在jsp頁(yè)面通過(guò)struts2標(biāo)簽的fielderror屬性輸出錯(cuò)誤信息。注意:struts2的校驗(yàn)在配置action的時(shí)候需要提供輸入頁(yè)面(就是<result name="input">)。這是對(duì)action中的所有方法進(jìn)行校驗(yàn)。 如果要對(duì)action中指定的方法進(jìn)行校驗(yàn),把validate方法名改為:validateXxx,其中Xxx是需要校驗(yàn)的指定方法名。 31,輸入校驗(yàn)的流程: ①類(lèi)型轉(zhuǎn)換器把請(qǐng)求參數(shù)進(jìn)行類(lèi)型轉(zhuǎn)換,并把轉(zhuǎn)換后的值賦給action中的屬性。 ②如果在執(zhí)行類(lèi)型轉(zhuǎn)換的過(guò)程中出現(xiàn)異常,系統(tǒng)會(huì)將異常信息保存到ActionContext中,conversionError攔截器將異常信息 添加到fieldErrors中。不管類(lèi)型轉(zhuǎn)換是否失敗都會(huì)轉(zhuǎn)入第三步。 ③系統(tǒng)通過(guò)反射技術(shù)調(diào)用action中的validateXxx方法。 ④再調(diào)用validate方法。 ⑤如果fieldErrors中存在錯(cuò)誤信息,系統(tǒng)自動(dòng)將請(qǐng)求轉(zhuǎn)發(fā)至input視圖。如果沒(méi)有錯(cuò)誤信息將執(zhí)行action中的方法。 注意:如果validate方法里沒(méi)有問(wèn)題,卻返回input頁(yè)面,可能是類(lèi)型轉(zhuǎn)換有問(wèn)題。所以返回input視圖有兩種原因(類(lèi)型轉(zhuǎn)換有問(wèn)題或校驗(yàn)出錯(cuò)). 32,基于xml配置方式對(duì)action內(nèi)所有的方法進(jìn)行校驗(yàn),xml文件的命名規(guī)則是:ActionClassName-validation.xml 如果只需要對(duì)action內(nèi)指定的方法進(jìn)行校驗(yàn),則xml文件的命名規(guī)則為:ActionClassName-ActionName-validation.xml。其 中ActionName(action的邏輯名稱)。它的配置一般用通配符(有助于實(shí)驗(yàn))。 ①基于xml配置方式的校驗(yàn),如果ActionClassName-validation.xml、ActionClassName-ActionName-validation.xml同時(shí)存在則把兩個(gè)文件匯總,在進(jìn)行校驗(yàn)。如果兩個(gè)xml文件的校驗(yàn)規(guī)則起了沖突則執(zhí)行后面的xml文件。 ②如果action繼承了另一個(gè)action則先找到父action校驗(yàn)文件,在找到子action校驗(yàn)文件,再把4(每個(gè)action都有指定方法名或非指定方法名)個(gè)文件匯總。 33,【國(guó)際化】。國(guó)際化按范圍分為:全局、action、package的范圍的資源文件。Properties文件命名的規(guī)則為:xxx_language_country.properties(xxx為用戶定義的名字,第二部分為語(yǔ)言類(lèi)別。) Ⅰ定義好了國(guó)際化文件后,需要在struts.xml文件配置<constants name="struts.custom.i18n.resources" value="國(guó)際化文件的名稱(xxx)">[這是定義全局的國(guó)際化資源文件],可以在jsp頁(yè)面顯示國(guó)際化信息<s:text name="key"/>。 Ⅱ也可以通過(guò)action類(lèi)繼承ActionSupport類(lèi),再調(diào)用個(gè)getText方法的資源文件的key(getText("key")).然后可以通過(guò)EL表達(dá)式在jsp頁(yè)面輸出。 Ⅲ也可以通過(guò)struts2的表單標(biāo)簽的key屬性。如<s:textfield key="key"/>或<s:textarea key="key"/> 輸出帶有占位符的國(guó)際化信息: ①<s:text name="key"><s:param>....</s:param>..</s:text> ②通過(guò)ActionSupport類(lèi)的getText(String key,String[] str)或者getText(String key,List list) 34,包范圍的國(guó)際化資源文件, 在大型的應(yīng)用程序中,整個(gè)應(yīng)用有大量的內(nèi)容需要國(guó)際化,如果我們把國(guó)際化的內(nèi)容放置在全局資源屬性文件中,顯然會(huì)導(dǎo)致資源文件變得過(guò)于龐大、臃腫,不便于維護(hù),這個(gè)時(shí)候我們需要針對(duì)不同的模塊,使用包范圍來(lái)組織國(guó)際化文件。 在java的包下創(chuàng)建名為:package_language_country.properties的資源文件,package為固定寫(xiě)法,language_country是對(duì)應(yīng)的語(yǔ)言類(lèi)別。處于該包及子包都可以訪問(wèn)該資源文件。當(dāng)在包范圍找不到對(duì)應(yīng)的資源文件,然后會(huì)在全局范圍內(nèi)查找。 35,Action范圍的資源文件。在Action所在的路徑創(chuàng)建名為:ActionClassName_language_country.properties 如果同時(shí)存在全局、package、Action范圍的國(guó)際化資源文件,系統(tǒng)搜索的順序是:Action-->package-->全局范圍。 36,以上三種配置有的是基于配置的國(guó)際化資源文件。我們也可以通過(guò)無(wú)配置的方式進(jìn)行直接訪問(wèn)某個(gè)資源文件。 通過(guò)struts2標(biāo)簽,如: <s:i18n name="xxx"> <s:text name="key"> </s:i18n> 其中xxx是全局范圍文件的名稱的前綴。 如果直接想訪問(wèn)包范圍的國(guó)際化資源文件 <s:i18n name="com.johnny.action.package"> <s:text name="key"> </s:i18n> 其中package是固定寫(xiě)法。 37,OGNL表達(dá)式(Object Graphic Navigation Language對(duì)象圖導(dǎo)航語(yǔ)言),當(dāng)struts2接受一個(gè)請(qǐng)求時(shí),會(huì)迅速創(chuàng)建ActionContext、ValueStack、action,然后把a(bǔ)ction存放在ValueStack,所以O(shè)GNL表達(dá)式可以迅速訪問(wèn)action實(shí)例的屬性。 OGNL表達(dá)式一般要配合Struts2標(biāo)簽使用。 在struts2中,EL表達(dá)式只能訪問(wèn)OgnlValueStack的root里的屬性。即action的屬性(因?yàn)閍ction的屬性放在OgnlValueStack的root屬性里)。利用OGNL表達(dá)式創(chuàng)建List/Map對(duì)象,<s:set var="" value="" scope=""/>scope指定變量的被放置的范圍,可以為application、session、request、page和action。如果沒(méi)有設(shè)置屬性,則默認(rèn)為OGNLContext(OGNL上下文)中,如果在OGNLContext訪問(wèn)時(shí)不用#,如果scope為request....中,則需要用#。value:賦給變量的值,如果沒(méi)有該屬性,則將ValueStack的棧頂?shù)闹蒂x給變量。 38,防止表單重復(fù)提交,首先要有struts的token標(biāo)簽。再使用系統(tǒng)的攔截器。 |
|