2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
1.????深入Struts2的配置文件 本部分主要介紹struts.xml的常用配置。
1.1.????包配置: Struts2框架中核心組件就是Action、攔截器等,Struts2框架使用包來(lái)管理Action和攔截器等。每個(gè)包就是多個(gè)Action、多個(gè)攔截器、多個(gè)攔截器引用的集合。 在struts.xml文件中package元素用于定義包配置,每個(gè)package元素定義了一個(gè)包配置。它的常用屬性有: l?name:必填屬性,用來(lái)指定包的名字。 l?extends:可選屬性,用來(lái)指定該包繼承其他包。繼承其它包,可以繼承其它包中的Action定義、攔截器定義等。 l?namespace:可選屬性,用來(lái)指定該包的命名空間。
| <! DOCTYPE? struts? PUBLIC ???????? "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" ???????? "http://struts.apache.org/dtds/struts-2.0.dtd" > < struts > ???? <!-- struts2 的 action 必須放在一個(gè)指定的包空間下定義 ?--> ???? < package? name = "default"? extends = "struts-default" > ???? <!--? 定義處理請(qǐng)求 URL 為 login.action 的 Action --> ???????? < action? name = "login"? class = "org.qiujy.web.struts.action.LoginAction" > ???????? <!--? 定義處理結(jié)果字符串和資源之間的映射關(guān)系 ?--> ???????????? < result? name = "success" > /success.jsp </ result > ???????????? < result? name = "error" > /error.jsp </ result > ???????? </ action > ???? </ package > </ struts > |
如上示例的配置,配置了一個(gè)名為default的包,該包下定義了一個(gè)Action。
1.2.????命名空間配置: 考慮到同一個(gè)Web應(yīng)用中需要同名的Action,Struts2以命名空間的方式來(lái)管理Action,同一個(gè)命名空間不能有同名的Action。 Struts2通過(guò)為包指定namespace屬性來(lái)為包下面的所有Action指定共同的命名空間。 把上示例的配置改為如下形式:
| <! DOCTYPE? struts? PUBLIC ???????? "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" ???????? "http://struts.apache.org/dtds/struts-2.0.dtd" > < struts > ???? <!-- struts2 的 action 必須放在一個(gè)指定的包空間下定義 ?--> ???? < package? name = "qiujy"? extends = "struts-default" > ???? <!--? 定義處理請(qǐng)求 URL 為 login.action 的 Action --> ???????? < action? name = "login"? class = "org.qiujy.web.struts2.action.LoginAction" > ???????? <!--? 定義處理結(jié)果字符串和資源之間的映射關(guān)系 ?--> ???????????? < result? name = "success" > /success.jsp </ result > ???????????? < result? name = "error" > /error.jsp </ result > ???????? </ action > ???? </ package > ??? ???? < package? name = "my"? extends = "struts-default"? namespace = "/manage" > ???? <!--? 定義處理請(qǐng)求 URL 為 login.action 的 Action --> ???????? < action? name = "backLogin"? class = "org.qiujy.web.struts2.action.LoginAction" > ???????? <!--? 定義處理結(jié)果字符串和資源之間的映射關(guān)系 ?--> ???????????? < result? name = "success" > /success.jsp </ result > ???????????? < result? name = "error" > /error.jsp </ result > ???????? </ action > ???? </ package > </ struts > |
如上配置了兩個(gè)包:default和my,配置my包時(shí)指定了該包的命名空間為/manage。 對(duì)于包default:沒(méi)有指定namespace屬性。如果某個(gè)包沒(méi)有指定namespace屬性,即該包使用默認(rèn)的命名空間,默認(rèn)的命名空間總是""。 對(duì)于包my:指定了命名空間/manage,則該包下所有的Action處理的URL應(yīng)該是“命名空間/Action名”。如上名為
backLogin的Action,它處理的URL為: http://localhost:8080/userlogin_struts2
/manage/backLogin.action Struts2的命名空間的作用等同于struts1里模塊的作用。
1.3.????包含配置: 在Struts2中可以將一個(gè)配置文件分解成多個(gè)配置文件,那么我們必須在struts.xml中包含其他配置文件。
| < struts > ???? < include? file = "struts-default.xml" /> ???? < include? file = "struts-user.xml" /> ???? < include? file = "struts-book.xml" /> ???? < include? file = "struts-shoppingCart.xml" /> ??? ??? ...... ??? </ struts > |
1.4.????攔截器配置: 見(jiàn)后面章節(jié)介紹。
1.5.????常量配置: Struts2框架有兩個(gè)核心配置文件,其中struts.xml文件主要負(fù)責(zé)管理應(yīng)用中的Action映射, 及Action處理結(jié)果和物理資源之間的映射關(guān)系。除此之外,Struts2框架還包含了一個(gè)struts.properties文件,該文件主義了Struts2框架的大量常量屬性。但通常推薦也是在struts.xml文件中來(lái)配置這些常量屬性。 如:后面會(huì)講到Struts2的國(guó)際化,它的資源文件位置就用常量屬性來(lái)指定:
| < struts > ??? ...... ???? < constant? name = "struts.custom.i18n.resources"? value = "messages" /> </ struts > |
表示指定了資源文件的放置在classes目錄下,基本名是messages,則在classes目錄下您就應(yīng)該放置類(lèi)似messages_zh_CN.properties,message_en.properties名的文件。
2.????Struts2的Action 2.1.????實(shí)現(xiàn)Action類(lèi): Struts2中Action是核心內(nèi)容,它包含了對(duì)用戶(hù)請(qǐng)求的處理邏輯,我們也稱(chēng)Action為業(yè)務(wù)控制器。 Struts2中的Action采用了低侵入式的設(shè)計(jì),Struts2不要求Action類(lèi)繼承任何的Struts2的基類(lèi)或?qū)崿F(xiàn)Struts2接口。(但是,我們?yōu)榱朔奖銓?shí)現(xiàn)Action,大多數(shù)情況下都會(huì)繼承com.opensymphony.xwork2.ActionSupport類(lèi),并重寫(xiě)此類(lèi)里的public String execute() throws Exception方法。因?yàn)榇祟?lèi)中實(shí)現(xiàn)了很多的實(shí)用接口,提供了很多默認(rèn)方法,這些默認(rèn)方法包括獲取國(guó)際化信息的方法、數(shù)據(jù)校驗(yàn)的方法、默認(rèn)的處理用戶(hù)請(qǐng)求的方法等,這樣可以大大的簡(jiǎn)化Action的開(kāi)發(fā)。) Struts2中通常直接使用Action來(lái)封裝HTTP請(qǐng)求參數(shù),因此,Action類(lèi)里還應(yīng)該包含與請(qǐng)求參數(shù)對(duì)應(yīng)的屬性,并且為屬性提供對(duì)應(yīng)的getter和setter方法。(當(dāng)然,Action類(lèi)中還可以封裝處理結(jié)果,把處理結(jié)果信息當(dāng)作一屬性,提供對(duì)應(yīng)的getter和setter方法) 修改第一部分的用戶(hù)登錄示例:把Action改成如下:
| package ?org.qiujy.web.struts2.action; import ?com.opensymphony.xwork2.ActionSupport; /** ? * @author qiujy ? * @version 1.0 ? */ public class ?LoginAction? extends ?ActionSupport { ???? private ?String? userName ; ???? private ?String? password ; ??? ???? private ?String? msg ;? // 結(jié)果信息屬性 ??? ???? /** ??? ? * @return the msg ??? ? */ ???? public ?String getMsg() { ???????? return msg ; ??? } ???? /** ??? ? * @param msg the msg to set ??? ? */ ???? public void ?setMsg(String msg) { ???????? this . msg ?= msg; ??? } ???? /** ??? ? * @return the userName ??? ? */ ???? public ?String getUserName() { ???????? return userName ; ??? } ???? /** ??? ? * @param userName the userName to set ??? ? */ ???? public void ?setUserName(String userName) { ???????? this . userName ?= userName; ??? } ???? /** ??? ? * @return the password ??? ? */ ???? public ?String getPassword() { ???????? return password ; ??? } ???? /** ??? ? * @param password the password to set ??? ? */ ???? public void ?setPassword(String password) { ???????? this . password ?= password; ??? } ??? ???? /** ??? ? * 處理用戶(hù)請(qǐng)求的 excute() 方法 ??? ? * @return 結(jié)果導(dǎo)航字符串 ??? ? * @throws Exception ??? ? */ ???? public ?String execute()? throws ?Exception{ ??????? if ( "test" .equals( this . userName ) && "test" .equals( this . password )){ ??????????? msg ?=? " 登錄成功,歡迎 " ?+? this . userName ; ??????????? return this . SUCCESS ; ?????? } else { ??????????? msg ?=? " 登錄失敗,用戶(hù)名或密碼錯(cuò) " ; ??????????? return this . ERROR ; ?????? } ??? } } |
往success.jsp和error.jsp頁(yè)面中添加 ${msg}?EL表達(dá)式來(lái)顯示結(jié)果信息。則最終效果跟以前一樣。
2.2.????Action訪(fǎng)問(wèn)Servlet API: Struts2中的Action并沒(méi)有和任何Servlet API耦合,這樣框架更具靈活性,更易測(cè)試。 但是,對(duì)于web應(yīng)用的控制器而言,不訪(fǎng)問(wèn)Servlet API幾乎是不可能的,例如跟蹤HTTP Session狀態(tài)等。Struts2框架提供了一種更輕松的方式來(lái)訪(fǎng)問(wèn)Servlet API。Struts2中提供了一個(gè)ActionContext類(lèi)(當(dāng)前Action的上下文對(duì)象),通過(guò)這個(gè)類(lèi)可以訪(fǎng)問(wèn)Servlet API。下面是該類(lèi)中提供的幾個(gè)常用方法: l?public static ActionContext getContext() :獲得當(dāng)前Action的ActionContext實(shí)例。 l?public Object get(Object key) :此方法類(lèi)似于調(diào)用HttpServletRequest的getAttribute(String name)方法。 l?public void put(Object key, Object value) :此方法類(lèi)似于調(diào)用HttpServletRequest 的setAttribute(String name, Object o)。 l?public Map getParameters() :獲取所有的請(qǐng)求參數(shù)。類(lèi)似于調(diào)用HttpServletRequest對(duì)象的getParameterMap() 方法。 l?public Map getSession() :返回一個(gè)Map對(duì)象,該Map對(duì)象模擬了HttpSession實(shí)例。 l?public void setSession(Map session) : 直接傳入一個(gè)Map實(shí)例,將該Map實(shí)例里的key-value對(duì)轉(zhuǎn)換成session的屬性名-屬性值對(duì)。 l?public Map getApplication() :返回一個(gè)Map對(duì)象,該對(duì)象模擬了該應(yīng)用的ServletContext實(shí)例。 l?public void setApplication(Map application) :直接傳入一個(gè)Map實(shí)例,將該Map實(shí)例里的key-value對(duì)轉(zhuǎn)換成application的屬性名-屬性值對(duì)。 修改以上用戶(hù)登錄驗(yàn)證示例的Action類(lèi)中的execute方法:
| public ?String execute()? throws ?Exception{ ???????? if ( "test" .equals( this . userName ) &&? "test" .equals( this . password )){ ???????????? msg ?=? " 登錄成功,歡迎 " ?+? this . userName ; ???????????? // 獲取 ActionContext 實(shí)例,通過(guò)它來(lái)訪(fǎng)問(wèn) Servlet API ??????????? ActionContext context = ActionContext.getContext(); ???????????? // 看 session 中是否已經(jīng)存放了用戶(hù)名,如果存放了:說(shuō)明已經(jīng)登錄了; // 否則說(shuō)明是第一次登錄成功 ???????????? if ( null ?!= context.getSession().get( "uName" )){ ???????????????? msg ?=? this . userName ?+? " :你已經(jīng)登錄過(guò)了 !!!" ; ??????????? } else { ??????????????? context.getSession().put( "uName" ,? this . userName ); ??????????? } ??????????? ???????????? return this . SUCCESS ; ??????? } else { ???????????? msg ?=? " 登錄失敗,用戶(hù)名或密碼錯(cuò) " ; ???????????? return this . ERROR ; ??????? } ??? } |
Struts2中通過(guò)ActionContext來(lái)訪(fǎng)問(wèn)Servlet API,讓Action徹底從Servlet API 中分離出來(lái),最大的好處就是可以脫離Web容器測(cè)試Action。 另外,Struts2中還提供了一個(gè)ServletActionContext類(lèi),Action只要繼承自該類(lèi),就可以直接訪(fǎng)問(wèn)Servlet API。具體方法參看struts2的API文檔。
3.????一個(gè)Action內(nèi)包含多個(gè)請(qǐng)求處理方法的處理 Struts1提供了DispatchAction,從而允許一個(gè)Action內(nèi)包含多個(gè)請(qǐng)求處理方法。Struts2也提供了類(lèi)似的功能。處理方式主要有以下三種方式:
3.1.????動(dòng)態(tài)方法調(diào)用: DMI:Dynamic Method Invocation 動(dòng)態(tài)方法調(diào)用。 動(dòng)態(tài)方法調(diào)用是指:表單元素的action不直接等于某個(gè)Action的名字,而是以如下形式來(lái)指定對(duì)應(yīng)的動(dòng)作名:
| <form method="post"?action="userOpt!login.action"> |
則用戶(hù)的請(qǐng)求將提交到名為”userOpt”的Action實(shí)例,Action實(shí)例將調(diào)用名為”login”方法來(lái)處理請(qǐng)求。同時(shí)login方法的簽名也是跟execute()一樣,即為public String login() throws Exception。 注意:要使用動(dòng)態(tài)方法調(diào)用,必須設(shè)置Struts2允許動(dòng)態(tài)方法調(diào)用,通過(guò)設(shè)置struts.enable.DynamicMethodInvocation常量來(lái)完成,該常量屬性的默認(rèn)值是true。
3.1.1.??????示例: 修改用戶(hù)登錄驗(yàn)證示例,多增加一個(gè)注冊(cè)用戶(hù)功能。 1.
???????修改Action類(lèi):
| package ?org.qiujy.web.struts2.action; import ?com.opensymphony.xwork2.ActionContext; import ?com.opensymphony.xwork2.ActionSupport; /** ? * @author qiujy ? * @version 1.0 ? */ public class ?LoginAction? extends ?ActionSupport{ ???? private ?String? userName ; ???? private ?String? password ; ??? ???? private ?String? msg ;? // 結(jié)果信息屬性 ??? ???? /** ??? ? * @return the msg ??? ? */ ???? public ?String getMsg() { ???????? return msg ; ??? } ???? /** ??? ? * @param msg the msg to set ??? ? */ ???? public void ?setMsg(String msg) { ???????? this . msg ?= msg; ??? } ???? /** ??? ? * @return the userName ??? ? */ ???? public ?String getUserName() { ???????? return userName ; ??? } ???? /** ??? ? * @param userName the userName to set ??? ? */ ???? public void ?setUserName(String userName) { ???????? this . userName ?= userName; ??? } ???? /** ??? ? * @return the password ??? ? */ ???? public ?String getPassword() { ???????? return password ; ??? } ???? /** ??? ? * @param password the password to set ??? ? */ ???? public void ?setPassword(String password) { ???????? this . password ?= password; ??? } ??? ???? /** ??? ? * 處理用戶(hù)請(qǐng)求的 login() 方法 ??? ? * @return 結(jié)果導(dǎo)航字符串 ??? ? * @throws Exception ??? ? */ ???? public ?String login()? throws ?Exception{ ???????? if ( "test" .equals( this . userName ) &&? "test" .equals( this . password )){ ???????????? msg ?=? " 登錄成功,歡迎 " ?+? this . userName ; ???????????? // 獲取 ActionContext 實(shí)例,通過(guò)它來(lái)訪(fǎng)問(wèn) Servlet API ??????????? ActionContext context = ActionContext.getContext(); ???????????? // 看 session 中是否已經(jīng)存放了用戶(hù)名,如果存放了:說(shuō)明已經(jīng)登錄了; // 否則說(shuō)明是第一次登錄成功 ???????????? if ( null ?!= context.getSession().get( "uName" )){ ???????????????? msg ?=? this . userName ?+? " :你已經(jīng)登錄過(guò)了 !!!" ; ??????????? } else { ??????????????? context.getSession().put( "uName" ,? this . userName ); ??????????? } ??????????? ???????????? return this . SUCCESS ; ??????? } else { ???????????? msg ?=? " 登錄失敗,用戶(hù)名或密碼錯(cuò) " ; ???????????? return this . ERROR ; ??????? } ??? } ??? ???? public ?String regist()? throws ?Exception{ ???????? // 將用戶(hù)名,密碼添加到數(shù)據(jù)庫(kù)中 ???????? //... ???????? msg ?=? " 注冊(cè)成功。 " ; ???????? return this . SUCCESS ; ??? } } |
2.
???????struts.xml文件:沒(méi)有什么變化,跟以前一樣配置
| <! DOCTYPE? struts? PUBLIC ???????? "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" ???????? "http://struts.apache.org/dtds/struts-2.0.dtd" > < struts > ???? < package? name = "my"? extends = "struts-default"? namespace = "/manage" > ???? <!--? 定義處理請(qǐng)求 URL 為 login.action 的 Action --> ???????? < action? name = "userOpt"? class = "org.qiujy.web.struts2.action.LoginAction" > ???????? <!--? 定義處理結(jié)果字符串和資源之間的映射關(guān)系 ?--> ???????????? < result? name = "success" > /success.jsp </ result > ???????????? < result? name = "error" > /error.jsp </ result > ???????? </ action > ???? </ package > </ struts > |
3.
???????頁(yè)面: index.jsp
| <%@? page? language = "java"? pageEncoding = "UTF-8" %> < html > ? < head > ???? < title > 用戶(hù)登錄頁(yè)面 </ title > ? </ head > ? ? < body > ?? < h2 > 用戶(hù)入口 </ h2 > ?? < hr > ???? < form? action = "manage/userOpt!login.action"? method = "post" > ???? < table? border = "1" > ??? ????? < tr > ??? ????????? < td > 用戶(hù)名: </ td > ??? ????????? < td >< input? type = "text"? name = "userName" /></ td > ??? ????? </ tr > ??? ????? < tr > ??? ????????? < td > 密碼: </ td > ??? ????????? < td >< input? type = "password"? name = "password" /></ td > ??? ????? </ tr > ??? ????? < tr > ??? ????????? < td? colspan = "2" > ??? ????????????? < input? type = "submit"? value = "? 確定 ?" /> ??? ????????? </ td > ??? ????? </ tr > ???? </ table > ???? </ form > ? </ body > </ html > |
regist.jsp
| <%@? page? language = "java"? pageEncoding = "UTF-8" %> < html > ? < head > ???? < title > 用戶(hù)注冊(cè)頁(yè)面 </ title > ? </ head > ? ? < body > ?? < h2 > 用戶(hù)注冊(cè) </ h2 > ?? < hr > ???? < form? action = "manage/userOpt!regist.action"? method = "post" > ???? < table? border = "1" > ??? ????? < tr > ??? ????????? < td > 用戶(hù)名: </ td > ??? ????????? < td >< input? type = "text"? name = "userName" /></ td > ??? ????? </ tr > ??? ????? < tr > ??? ????????? < td > 密碼: </ td > ??? ????????? < td >< input? type = "password"? name = "password" /></ td > ??? ????? </ tr > ??? ????? < tr > ??? ????????? < td? colspan = "2" > ??? ????????????? < input? type = "submit"? value = "? 注冊(cè) ?" /> ??? ????????? </ td > ??? ????? </ tr > ???? </ table > ???? </ form > ? </ body > </ html > |
4.
???????運(yùn)行結(jié)果:
3.2.????為Action配置method屬性: 將Action類(lèi)中的每一個(gè)處理方法都定義成一個(gè)邏輯Action方法。
| <! DOCTYPE? struts? PUBLIC ???????? "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" ???????? "http://struts.apache.org/dtds/struts-2.0.dtd" > < struts > ???? < package? name = "my"? extends = "struts-default"? namespace = "/manage" > ???????? < action? name = "userLogin"? class = "org.qiujy.web.struts2.action.LoginAction"? method = "login" > ???????????? < result? name = "success" > /success.jsp </ result > ???????????? < result? name = "error" > /error.jsp </ result > ???????? </ action > ??????? ???????? < action? name = "userRegist"? class = "org.qiujy.web.struts2.action.LoginAction" method = "regist" > ???????????? < result? name = "success" > /success.jsp </ result > ???????????? < result? name = "error" > /error.jsp </ result > ???????? </ action > ???? </ package > </ struts > |
如上,把LoginAction中的login和regist方法都配置成邏輯Action。要調(diào)用login方法,則相應(yīng)的把index.jsp中表單元素的action設(shè)置為"manage/userLogin.action";要調(diào)用regist方法,把regist.jsp中表單元素的action設(shè)置為"manage/userRegist.action"。
3.3.????使用通配符映射(wildcard mappings)方式: 在struts.xml文件中配置<action…>元素時(shí),它的name、class、method屬性都可支持通配符,這種通配符的方式是另一種形式的動(dòng)態(tài)方法調(diào)用。 當(dāng)我們使用通配符定義Action的name屬性時(shí),相當(dāng)于用一個(gè)元素action定義了多個(gè)邏輯Action:
| < action? name = "user_*" class = "org.qiujy.web.struts2.action.UserAction"? method = "{1}" > ???????????? < result? name = "success" > /success.jsp </ result > ???????????? < result? name = "error" > /error.jsp </ result > ???????? </ action > |
如上,<action name=”user_*”>定義一系列請(qǐng)求URL是user_*.action模式的邏輯Action。同時(shí)method屬性值為一個(gè)表達(dá)式{1},表示它的值是name屬性值中第一個(gè)*的值。例如:用戶(hù)請(qǐng)求URL為user_login.action時(shí),將調(diào)用到UserAction類(lèi)的login方法;用戶(hù)請(qǐng)求URL為user_regist.action時(shí),將調(diào)用到UserAction類(lèi)的regist方法。
4.????處理結(jié)果 Struts2的Action處理完用戶(hù)請(qǐng)求后,將返回一個(gè)普通字符串,整個(gè)普通字符串就是一個(gè)邏輯視圖名。Struts2通過(guò)配置邏輯視圖名和物理視圖資源之間的映射關(guān)系,一旦系統(tǒng)收到Action返回的某個(gè)邏輯視圖名,系統(tǒng)就會(huì)把對(duì)應(yīng)的物理視圖資源呈現(xiàn)給瀏覽者。
4.1.????配置處理結(jié)果: Struts2的Action處理用戶(hù)請(qǐng)求結(jié)束后,返回一個(gè)普通字符串-邏輯視圖名,必須在struts.xml文件中完成邏輯視圖和物理視圖資源的映射,才可讓系統(tǒng)轉(zhuǎn)到實(shí)際的視圖資源。 Struts2通過(guò)在struts.xml文件中使用<result …/>元素來(lái)配置結(jié)果。Struts2提供了兩種結(jié)果。 l?局部結(jié)果:將<result …/>作為<action …>元素的子元素配置。 l?全局結(jié)果:將<result …/>作為<global-results …>元素的子元素配置。 在package元素中配置<global-results>子元素:
| <global-results> <result name="error">/Error.jsp</result> <result name="invalid.token">/Error.jsp</result> <result name="login" type="redirect-action">Logon!input</result> </global-results> |
4.2.????處理結(jié)果類(lèi)型: Struts2提供了對(duì)不同種類(lèi)返回結(jié)果的支持,常見(jiàn)的有JSP,FreeMarker,Velocity等。 Struts2支持的不同類(lèi)型的返回結(jié)果為:
| 名字 | 說(shuō)明 |
| chain | 用來(lái)處理Action鏈 |
| dispatcher | 用來(lái)轉(zhuǎn)向頁(yè)面,通常處理JSP,這是默認(rèn)的結(jié)果類(lèi)型 |
| freeMarker | 處理FreeMarker模板 |
| httpHeader | 用來(lái)控制特殊的Http行為 |
| redirect | 重定向到一個(gè)URL |
| redirect-action | 重定向到一個(gè)Action |
| stream | 向?yàn)g覽器發(fā)送InputSream對(duì)象,通常用來(lái)處理文件下載 |
| velocity | 處理Velocity模板 |
| xslt | 處理XML/XLST模板 |
| plaintext | 顯示原始文件內(nèi)容,例如文件源代碼 |
| tiles | 結(jié)合Tile使用 |
另外第三方的Result類(lèi)型還包括JasperReports Plugin,專(zhuān)門(mén)用來(lái)處理JasperReport類(lèi)型的報(bào)表輸出;Jfreechart Plugin;JSF Plugin。
4.3.????動(dòng)態(tài)返回結(jié)果 有些時(shí)候,只有當(dāng)Action執(zhí)行完畢的時(shí)候我們才知道要返回哪個(gè)結(jié)果,這個(gè)時(shí)候我們可以在Action內(nèi)部定義一個(gè)屬性,這個(gè)屬性用來(lái)存儲(chǔ)Action執(zhí)行完畢之后的result值,例如:
| private String nextAction; public String getNextAction() { return nextAction; } |
在strutx.xml配置文件中,我們可以使用${nextAction}來(lái)引用到Action中的屬性,通過(guò)${nextAction}表示的內(nèi)容來(lái)動(dòng)態(tài)的返回結(jié)果,例如:
| <action name="fragment" class="FragmentAction"> <result name="next" type="redirect-action">${nextAction}</result> </action> |
上述Action的execute方法返回next的時(shí)候,還需要根據(jù)nextAction的屬性來(lái)判斷具體定位到哪個(gè)Action。
5.????屬性驅(qū)動(dòng)和模型驅(qū)動(dòng) 不管屬性驅(qū)動(dòng)還是模型驅(qū)動(dòng),Struts2框架都是通過(guò)攔截器負(fù)責(zé)提取請(qǐng)求參數(shù),并將請(qǐng)求數(shù)據(jù)封裝到相應(yīng)的Action實(shí)例的屬性或?qū)iT(mén)的模型的屬性。
5.1.????屬性驅(qū)動(dòng): 屬性驅(qū)動(dòng)就是屬性(property)作為貫穿MVC流程的信息攜帶者。簡(jiǎn)單的說(shuō),就是使用Action實(shí)例來(lái)封裝請(qǐng)求參數(shù)和處理結(jié)果信息。前面我們做的示例都屬于屬性驅(qū)動(dòng)模式。
5.2.????模型驅(qū)動(dòng): 模型驅(qū)動(dòng)就是使用單獨(dú)的javaBean作為貫穿整個(gè)MVC流程的信息攜帶者。也就是說(shuō),使用單獨(dú)的VO(值對(duì)象)來(lái)封裝請(qǐng)求參數(shù)和處理結(jié)果信息。 示例:繼續(xù)修改用戶(hù)登錄驗(yàn)證: 1.
???????新增一用戶(hù)域模型對(duì)象:User.java
| package ?org.qiujy.domain; public class ?User { ???? private ?String? userName ; ???? private ?String? password ; ???? /** ??? ? * @return the userName ??? ? */ ???? public ?String getUserName() { ???????? return userName ; ??? } ???? /** ??? ? * @param userName the userName to set ??? ? */ ???? public void ?setUserName(String userName) { ???????? this . userName ?= userName; ??? } ???? /** ??? ? * @return the password ??? ? */ ???? public ?String getPassword() { ???????? return password ; ??? } ???? /** ??? ? * @param password the password to set ??? ? */ ???? public void ?setPassword(String password) { ???????? this . password ?= password; ??? } } |
2.
???????業(yè)務(wù)控制器:UserAction.java
| package ?org.qiujy.web.struts2.action; import ?org.qiujy.domain.User; import ?com.opensymphony.xwork2.ActionContext; import ?com.opensymphony.xwork2.ActionSupport; public class ?UserAction? extends ?ActionSupport{ ???? // 定義用于封裝請(qǐng)求參數(shù)的模型對(duì)象 ???? private ?User? user ?=? new ?User(); ??? ???? private ?String? msg ;? // 結(jié)果信息屬性 ??? ???? /** ??? ? * @return the user ??? ? */ ???? public ?User getUser() { ???????? return user ; ??? } ???? /** ??? ? * @param user the user to set ??? ? */ ???? public void ?setUser(User user) { ???????? this . user ?= user; ??? } ???? /** ??? ? * @return the msg ??? ? */ ???? public ?String getMsg() { ???????? return msg ; ??? } ???? /** ??? ? * @param msg the msg to set ??? ? */ ???? public void ?setMsg(String msg) { ???????? this . msg ?= msg; ??? } ??? ???? /** ??? ? * 處理用戶(hù)請(qǐng)求的 login() 方法 ??? ? * @return 結(jié)果導(dǎo)航字符串 ??? ? * @throws Exception ??? ? */ ???? public ?String login()? throws ?Exception{ ??????? String userName =? user .getUserName(); ??????? String password =? user .getPassword(); ??????? ???????? if ( "test" .equals(userName) &&? "test" .equals(password)){ ???????????? msg ?=? " 登錄成功,歡迎 " ?+ userName; ???????????? // 獲取 ActionContext 實(shí)例,通過(guò)它來(lái)訪(fǎng)問(wèn) Servlet API ??????????? ActionContext context = ActionContext.getContext(); ???????????? // 看 session 中是否已經(jīng)存放了用戶(hù)名,如果存放了:說(shuō)明已經(jīng)登錄了;否則說(shuō)明是第一次登錄成功 ???????????? if ( null ?!= context.getSession().get( "uName" )){ ???????????????? msg ?= userName +? " :你已經(jīng)登錄過(guò)了 !!!" ; ??????????? } else { ??????????????? context.getSession().put( "uName" , userName); ??????????? } ??????????? ???????????? return this . SUCCESS ; ??????? } else { ???????????? msg ?=? " 登錄失敗,用戶(hù)名或密碼錯(cuò) " ; ???????????? return this . ERROR ; ??????? } ??? } ??? ???? public ?String regist()? throws ?Exception{ ???????? // 將用戶(hù)名,密碼添加到數(shù)據(jù)庫(kù)中 ???????? //... ???????? msg ?=? " 注冊(cè)成功。 " ; ???????? return this . SUCCESS ; ??? } } |
3.
???????配置文件:struts.xml
| <! DOCTYPE? struts? PUBLIC ???????? "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" ???????? "http://struts.apache.org/dtds/struts-2.0.dtd" > < struts > ???? < package? name = "my"? extends = "struts-default"? namespace = "/manage" > ???????? < action? name = "userOpt"? class = "org.qiujy.web.struts2.action.UserAction" > ???????????? < result? name = "success" > /success.jsp </ result > ???????????? < result? name = "error" > /error.jsp </ result > ???????? </ action > ???? </ package > </ struts > |
4.
???????頁(yè)面: index.jsp
| <%@? page? language = "java"? pageEncoding = "UTF-8" %> < html > ? < head > ???? < title > 用戶(hù)登錄頁(yè)面 </ title > ? </ head > ? ? < body > ?? < h2 > 用戶(hù)入口 </ h2 > ?? < hr > ???? < form? action = "manage/userOpt!login.action"? method = "post" > ???? < table? border = "1" > ??? ????? < tr > ??? ????????? < td > 用戶(hù)名: </ td > ??? ????????? < td > < input? type = "text"? name = "user.userName" /> </ td > ??? ????? </ tr > ??? ????? < tr > ??? ????????? < td > 密碼: </ td > ??? ????? < td > <input type="password" name="user.password"/> </ td > ??? ????? </ tr > ??? ????? < tr > ??? ????????? < td? colspan = "2" > ??? ????????????? < input? type = "submit"? value = "? 確定 ?" /> ??? ????????? </ td > ??? ????? </ tr > ???? </ table > ???? </ form > ? </ body > </ html > |
其它頁(yè)面略。 5.
???????運(yùn)行效果:同以前一樣。 6.
???????源代碼:
6.????Struts2的異常處理機(jī)制: 任何成熟的MVC框架都應(yīng)該提供成就的異常處理機(jī)制。Strut2也不例外。Struts2提供了一種聲明式的異常處理方式。Struts2也是通過(guò)配置的攔截器來(lái)實(shí)現(xiàn)異常處理機(jī)制的。 Struts2的異常處理機(jī)制通過(guò)在struts.xml文件中配置<exception-mapping …>元素完成的,配置該元素時(shí),需要指定兩個(gè)屬性: exception:此屬性指定該異常映射所設(shè)置的異常類(lèi)型。 result:此屬性指定Action出現(xiàn)該異常時(shí),系統(tǒng)轉(zhuǎn)入result屬性所指向的結(jié)果。
6.1.????異常映射也分為兩種: l?局部異常映射:<exception-mapping…>元素作為<action…>元素的子元素配置。 l?全局異常映射:<exception-mapping…>元素作為<global-exception-mappings>元素的子元素配置。
6.2.????輸出異常信息: 使用Struts2的標(biāo)簽來(lái)輸出異常信息: l?<s:property value="exception.message"/> : 輸出異常對(duì)象本身。 l?<s:property value="exceptionStack"/> : 輸出異常堆棧信息。
6.3.????示例: 還是修改用戶(hù)登錄示例: 1)
??????把UserAciton.java中的regist方法改成:
| public ?String regist()? throws ?Exception{ ???????? // 將用戶(hù)名,密碼添加到數(shù)據(jù)庫(kù)中 ???????? //... ???????? //msg = " 注冊(cè)成功。 "; ???????? if ( true ){ ??????????? throw new ?java.sql.SQLException( " 沒(méi)有數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序 " ); ?????? } ??????? ???????? return this.SUCCESS; ??? } |
2)
??????修改struts.xml文件:
| <! DOCTYPE? struts? PUBLIC ???????? "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" ???????? "http://struts.apache.org/dtds/struts-2.0.dtd" > < struts > ???? < package? name = "my"? extends = "struts-default"? namespace = "/manage" > ???????? <!--? 定義全局處理結(jié)果 ?--> ???????? < global-results > ???????? <!--? 邏輯名為 sql 的結(jié)果,映射到 /exception.jsp 頁(yè)面 ?--> ???????? < result? name = "sql" > /exception.jsp </ result > ???????? </ global-results > ??????? ???????? < global-exception-mappings > ???????? <!--? 當(dāng) Action 拋出 SQLException 異常時(shí),轉(zhuǎn)入名為 sql 的結(jié)果 ?--> ???????? < exception-mapping? exception = "java.sql.SQLException"? result = "sql" /> ???????? </ global-exception-mappings > ??????? ???????? < action? name = "userOpt"? class = "org.qiujy.web.struts2.action.UserAction" > ???????????? < result? name = "success" > /success.jsp </ result > ???????????? < result? name = "error" > /error.jsp </ result > ???????? </ action > ???? </ package > </ struts > |
3)
??????新增一頁(yè)面:exception.jsp
| <%@? page? language = "java"? pageEncoding = "utf-8" %> <%@? taglib? uri = "/struts-tags"? prefix = "s"? %> < html > ? < head > ???? < title > 異常信息 </ title > ? </ head > ? ? < body > ? < h2 > ? 出現(xiàn)異常啦 ? </ h2 > ? < hr /> ??? < h3? style = "color:red" > ??? <!--? 獲得異常對(duì)象 ?--> ???? < s:property? value = "exception.message" /> ???? </ h3 > ???? < br /> ???? <!--? 異常堆棧信息 ?--> ???? < s:property? value = "exceptionStack" /> </ html > |
4)
??????運(yùn)行regist.jsp進(jìn)行調(diào)試:
轉(zhuǎn)載于:https://my.oschina.net/softwarechina/blog/135951
總結(jié)
以上是生活随笔為你收集整理的Struts2 XML配置详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。