效果圖
在此用我們前面所了解的Struts來制作一個簡單的流言板。
這么樣,通過幾副圖,我想大家對這個留言板的大至流程已經(jīng)有個了解了吧,它還是我們前面那個登錄驗證的例子,只不過,界面我稍微美化了一下,沒想吧,我們竟然用了一個登錄驗證的例子,進行進階,學(xué)習(xí)完struts這個系列的教程,是的,就這么簡單,希望大家在學(xué)習(xí)別的語言時,也這么去做,你會發(fā)現(xiàn)你進步的很快,不妨可以去試試,希望大家關(guān)注我的其他系列的教程哦。
程序流程設(shè)計及實現(xiàn)
一、 數(shù)據(jù)庫
這個示例主要是對兩個表的管理。
1) 用戶表
CREATE TABLE `user` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(100) default NULL,
`password` varchar(100) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2) 留言表
CREATE TABLE `guestbook` (
`id` int(11) NOT NULL auto_increment,
`user_id` int(11) default NULL,
`message` text,
`date` datetime default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
二、 模型層
因為這是個簡單的示例,模型我們就用JDBC把,在日后的進階中你可以改成Hibernate的。接下來,我們分別建立兩個bean:
1) userBean.java
public class UserBean
implements Serializable {
private int id;
private String username;
private String password;
public UserBean() {
}
setXXX()和getXXX()
}
2) GuestbookBean.java
public class GuestbookBean
implements Serializable {
private int id;
private String username;
private String message;
private String date;
private DataSource dataSource;
public GuestbookBean() {
}
setXXX()和getXXX();
}
三、 Controller(控制層)
一、 修改Action
LoginAction.java
LoginActionForm loginform = (LoginActionForm) actionForm;
HttpSession session = request.getSession();
String username = loginform.getUsername();
String userpass = loginform.getUserpass();
//獲取ServletContext對象
ServletContext ctx = servlet.getServletContext();
//獲取數(shù)據(jù)連接對象
DataSource ds = (DataSource) ctx.getAttribute("DataSource");
//因為邏輯處理我沒用DAO,交給Bean處理了,所以需要一個數(shù)據(jù)連接對象
UserBean userBean = new UserBean(ds);
String actionpath = "";
//我在userBean中加的isLogin方法,用于驗證用戶登錄是否成功,如果成功的化返回
返回true,否則返回false(表示登錄失敗,改用戶不存在)。
boolean flag = userBean.isLogin(username,userpass);
if (flag) {
//當(dāng)用戶登錄成功,我們要顯示所有的留言,所以還得需要一個//GuestbookBean。這個bean也需要一個ds對象,因為它的getGuestbook方法//是返回所有的流言。
GuestbookBean gb = new GuestbookBean(ds);
//把userBean設(shè)置到session中,當(dāng)用戶發(fā)表評論是顯示其用戶的名稱,以達(dá) //到用戶與留言關(guān)聯(lián)起來
session.setAttribute("userBean", getUserBean(username,userpass));
//取得留言集合放到request中,馬上到頁面顯示出來。
request.setAttribute("guestBookList", gb.getGuestbook());
actionpath = "success";
} else {
actionpath = "error";
}
return actionMapping.findForward(actionpath);
}
二、 新建一個GuestbookOptAction.
有兩個方法,getAllGuestbook()和addGuestbook(),分別是獲取所有的留言、增加留言。
創(chuàng)建一個FormBean
public class GuestbookForm
extends ActionForm {
private String message;
setXXX()和getXXX();
}
創(chuàng)建GuestbookOptAction.java
public class GuestbookOptAction
extends DispatchAction {
public ActionForward getAllGuestbook(ActionMapping mapping,
ActionForm actionForm,
HttpServletRequest request,
HttpServletResponse response) {
ServletContext ctx = servlet.getServletContext();
DataSource ds = (DataSource) ctx.getAttribute("DataSource");
GuestbookBean gb = new GuestbookBean(ds);
request.setAttribute("guestBookList", gb.getGuestbook());
return mapping.findForward("goToGuestbookPage");
}
public ActionForward addGuestbook(ActionMapping mapping,
ActionForm actionForm,
HttpServletRequest request,
HttpServletResponse response) {
GuestbookForm gurestbookForm =(GuestbookForm) actionForm;
ServletContext ctx = servlet.getServletContext();
DataSource ds = (DataSource) ctx.getAttribute("DataSource");
GuestbookBean gb = new GuestbookBean(ds);
//取得用戶留言內(nèi)容
gb.setMessage(gurestbookForm.getMessage());
//獲取session這個用戶的編號
int userId = Integer.parseInt(request.getParameter("userId"));
//添加一個留言,這里userId告訴程序,用戶與留言進行關(guān)聯(lián)
gb.addGuestbook(gb, userId);
//去得所有留言
return getAllGuestbook(mapping,actionForm,request,response);
}
四、 修改struts-config.xml
<action
path="/login"
name="loginActionForm"
scope="request"
type="org.zhoudq.webapp.action.LoginAction"
validate="true"
input="/login.jsp">
<forward name="success" path="/guestbook.jsp" />
<forward name="error" path="/login.jsp" />
</action>
<action
path="/getGuestBook"
name="guestbookForm"
parameter="method"
type="org.zhoudq.webapp.action.GuestbookOptAction">
<forward name="goToGuestbookPage" path="/guestbook.jsp"/>
</action>
五、 頁面(View)
Login.jsp、guestbook.jsp
流程也就就用戶登錄成功,在guestbook.jsp顯示所有的流言列表,然后可以添加留言。
因為頁面設(shè)計后,代碼變多了,這里就不貼出來了。如果想索取程序,請與本人聯(lián)系,
Email:zhdqCN@gmail.com。
六、 運行測試
打開瀏覽器,鍵入:http://localhost:8080/Struts1_Login/
就可以操作了,就能看到上面的畫面了,一個登錄示例帶著我們學(xué)會了如何去用Struts,不過Struts遠(yuǎn)遠(yuǎn)不只是這寫,希望大家繼續(xù)學(xué)習(xí),有什么問題日后大家可以互相交流,哈。
在使用Struts框架時,每個請求都由Action去處理,并且還要在struts-config.xml中加以設(shè)定,這樣以來做小項目還行,在大型網(wǎng)站的開發(fā)中,有很多小組負(fù)責(zé)不同的模塊,如果每一個小組要對一個struts-config.xml進行設(shè)定,將會導(dǎo)致struts-config.xml的版本控制問題。
您可以為每個小組分配不同的struts-config.xml設(shè)定文件,方法是在ActionServlet參數(shù)的config參數(shù)后面加上后綴,如果是config/admin,那么相應(yīng)的配置文件的名字就是:struts-config-admin,他們的后綴名字必須對應(yīng),這樣才能映射上。
例如我們可以把后臺處理分配一個小組,設(shè)定具體代碼如下所示:web.xml
<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/conf/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>config/admin</param-name>
<param-value>/WEB-INF/conf/struts-confg-admin.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>3</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
config/admin:指定了admin模塊的所使用的配置文件是struts-config-admin.xml,現(xiàn)在負(fù)責(zé)后臺模塊的開發(fā)人員只要管理自己的開發(fā)文檔設(shè)定就行了,就像前面所說的一樣,當(dāng)ActionServlet收到請求時,它是根據(jù)模塊你所指定的后綴,進行處理是哪個模塊的請求。
例如:
http://localhost:8080/strutsmodel/admin/admin.do
這個URL,表示請求由strutsmodel工程的admin環(huán)境的admin.do來處理這個請求。這樣以來前臺和后臺就分明了,各自開發(fā)各自的,各自管理自己的配置文件,達(dá)到松耦合的目的。
當(dāng)ActionServlet請求接收請求,它判斷URL中相對與context的前綴,例如上例中的admin,于是就知道應(yīng)該使用admin模塊。下面是struts-config-admin.xml:
……
<action
path="/admin"
type="org.zhoudq.webapp.action.AdminAction" >
<forward name="admin" path="/admin.jsp" />
</action>
……
這樣以來所有的path設(shè)定將自動被加上login前綴,例如必須使用以下的路徑才可以正確的請求到AdminAction:
http://localhost:8080/strutsmodel/admin/admin.do
在模塊中的Action在查找forward時,都是以所在模塊,查找對應(yīng)的struts-confg-XXX.xml的,例如上面的AdminAction在查找forward時,則會查找struts-config-admin.xml中的forward元素,也就是說,模塊中的forward對象的查找都是相對于模塊的路徑的,而不是相對與環(huán)境上下文。
那么我們模塊分配工作幾已經(jīng)搞定了,各個小組可以分別開工了,但是問題來了,那么如何從當(dāng)前的模塊換到另一個模塊呢?
當(dāng)您的項目分作很多個模塊時,在使用者點某個鏈接時,您有兩個方法可以在模塊之間切換。
一、方法一
是使用相對與環(huán)境上下文的路徑進行forward轉(zhuǎn)發(fā),您可以在當(dāng)前的struts-config-XX.xml如下設(shè)定,例如是:struts-config-admin.xml中加入:
<global-forwards>
<forward
name="switchModuleToFront"
contextRelative="true"
path="/front/login.do"
redirect="true"/>
</global-forwards>
這個是全局可以找到的forward中設(shè)定的,下面是在action元素中設(shè)定如何轉(zhuǎn)發(fā)模塊,代碼如下:
……
<action
path="/admin"
type="org.zhoudq.webapp.action.AdminAction" >
<forward
name="admin"
contextRelative="true"
path="/front/login.do"
redirect="true"/>
</action>
……
上面這種配置就是通過forward元素轉(zhuǎn)換到相應(yīng)的模塊,下面我們看另一種方法吧。
二、方法二
這種方法是我們通過配置Struts的一個特定的類SwitchAction,就能實現(xiàn)上面的要求了。并且需要兩個參數(shù):
1. prefix:用來指定模塊的后綴名稱
2. page:用來指定你的資源路徑。
例如:
……
<action-mappings>
<action
path="/switch"
type="org.apache.struts.actions.SwitchAction"/>
</action-mappings>
……
例如:
http://localhost:8080/strutsmodel/switch.do?prefix=/admin&page=/admin.do
這個是訪問我們后臺模塊的admin.do資源。模塊化決絕了我們開發(fā)中的不少問題吧,希望能幫助您解決一些問題,嘿嘿,加油吧……
一、Struts的ActionForm的表單驗證
ActionForm類用于在視圖層和控制層之間傳遞HTML表單數(shù)據(jù)??刂茖涌梢詮?/span>ActionForm Bean中讀取用戶輸入的表單數(shù)據(jù),也可以把來自模型層的數(shù)據(jù)存放到ActionForm Bean中,然后把數(shù)據(jù)返回給視圖。即ActionForm Bean從HTML表單中獲取用戶輸入的數(shù)據(jù)并將傳遞給Action類,也可以把從業(yè)務(wù)層返回的數(shù)據(jù)用來填充ActionForm Bean,然后JSP頁面用它來為HTML表單提供各種輸出字段的數(shù)據(jù)。此外,ActionForm Bean還具有表單驗證功能,可以過路不合法的數(shù)據(jù)。
ActionForm Bean有兩種存在范圍:request和session。如果ActionForm Bean存在于request范圍,它僅在當(dāng)前的請求/響應(yīng)生命周期中有效。如果ActionForm Bean存在于session范圍,同一個ActionForm Bean實例在整個HTTP會話中都有效。
在Struts框架中,使用ActionForm Bean來實現(xiàn)應(yīng)用程序系統(tǒng)的非持久性數(shù)據(jù)存儲和維護功能,它采用了自動填充屬性和調(diào)用的機制。所以必須繼承ActionForm類,并且包涵用戶表單輸入的屬性,以及相應(yīng)的get方法和set方法。另外,還可以根據(jù)需要重寫父類的reset()和validate()方法,實現(xiàn)屬性的重置和表單數(shù)據(jù)驗證功能。
Ø validate()方法
這個方法主要負(fù)責(zé)檢查數(shù)據(jù)的格式和語法,而不負(fù)責(zé)檢查數(shù)據(jù)是否符合業(yè)務(wù)邏輯。
ActionForm基類中的validate()方法在默認(rèn)情況下將返回null。如果創(chuàng)建了ActionForm的子類,那么應(yīng)該在子類覆蓋validate()方法。
Ø reset()方法
這個方法用于恢復(fù)ActionForm Bean 的屬性的默認(rèn)值。例如:把字符串屬性設(shè)為null或某個初始值。
1、 修改前面我們寫的LoginActionForm,如果你不清楚的話,請您先看前幾個實例,具體代碼如下:
public ActionErrors validate(ActionMapping actionMapping,
HttpServletRequest httpServletRequest) {
ActionErrors errors = new ActionErrors();
if (username == null|| username.equals("")) {
errors.add(ActionErrors.GLOBAL_MESSAGE,
new ActionError("loginform.error.username"));
}
if (userpass == null||userpass.equals("")) {
errors.add(ActionErrors.GLOBAL_MESSAGE,
new ActionError("loginform.error.password"));
}
return errors;
}
這個方法返回ActionErrors對象,如果返回的ActionErrors對象為null,或者不包含任何ActionMessage對象,就表示沒有錯誤,數(shù)據(jù)驗證通過。如果ActionErrors中包含ActionMessage對象,就表示發(fā)生了驗證錯誤,此時就回把請求轉(zhuǎn)發(fā)到你struts.xml里面<action>元素input屬性指定的web資源。
new ActionError("loginform.error.username");取得資源文件里面的鍵值,用于頁面的輸出。
2、 打開applicationResource.properties,加入如下信息:
loginform.error.username=please enter your username
loginform.error.password=please enter your password
因為我們前面做了國際化,所以打開applicationResource_zh_CN.properties文件,添加如下:
loginform.error.username=請輸入用戶名
loginform.error.password=請輸入密碼
3、 修改struts-config.xml文件
<action
path="/login"
name="loginActionForm"
scope="request"
type="actions.LoginAction"
validate="true"
input="/login.jsp">
<forward name="success" path="/success.jsp" />
<forward name="error" path="/wrong.jsp" />
</action>
在<action>元素中,name和scope屬性分別指定ActionForm的名字和它的范圍,valudate屬性指定是否執(zhí)行表單驗證,而input屬性表示驗證失敗,所要顯示用戶的內(nèi)容。
4、 修改login.jsp,在<body>元素添加,目的是顯示錯誤信息,具體代碼片段如下:
<div>
<font color="red">
<html:messages id="error">
<li><bean:write name="error"/></li>
</html:messages>
</font>
</div>
<html:message/> :用于輸出消息。屬性介紹如下:
n name:指定ActionMessages對象存放在request或session范圍內(nèi)的屬性key。標(biāo)簽處理類將根據(jù)這一屬性key來檢索request或session范圍的ActionMessages對象。
n message屬性:指定消息的來源。如果為true,則從request或session范圍內(nèi)檢索出屬性key為Globals.MESSAGE_KEY的ActionMessages對象,此時name屬性無效;如果為false,則根據(jù)name屬性來檢索ActionMessage對象,如果此時沒有設(shè)置name屬性,將采取默認(rèn)值Globals.ERROR_KEY.message屬性的默認(rèn)值為false。
n id屬性:用來命名從消息中檢索出來的每個ActionMessage對象,它和<bean:write>標(biāo)簽的name屬性匹配。
<bean:write/>:表示顯示javaBean或其屬性的內(nèi)容。
5、 運行
打開IE,鍵入如下地址:http://localhost:8080/Struts1_Login/login.jsp
不輸入任何東西,我們直接點幾擊“確定”,如下:
二、Struts的Validator驗證框架
Validator 目前是Jakarta Commons 項目的一部分,它也被包含在Struts主分發(fā)里面,可以直接使用Struts 中自帶的Validator 庫,也可以去網(wǎng)站上下載http://jakarta.apache.org/commons/。
Struts框架能夠通過ActionForm Bean的validate()方法對用戶輸入的表單數(shù)據(jù)進行驗證。但是這種驗證方式又有一定的局限性。必須由具體的代碼來實現(xiàn)驗證邏輯,如果驗證邏輯發(fā)生了改變,就需要重新編寫程序代碼。此外,如果系統(tǒng)中有多個ActionForm Bean,并且他們包含一些相同的驗證邏輯時,那么開發(fā)人員必須對每個ActionForm Bean進行重復(fù)開發(fā)呢?
Validator框架能夠克服在ActionForm Bean中進行數(shù)據(jù)驗證的局限性,它允許為Struts應(yīng)用靈活的配置驗證規(guī)則,無需編程。
Validator框架主要依賴于兩個JAR文件:
Ø Jakarta-oro.jar
提供了一組處理文本的類,具有文本替換,過錄和分割等功能。
Ø commons-validator.jar
提供了一個簡單、可擴展的驗證框架,包含了通用的驗證方法和驗證規(guī)則。
主要的Struts驗證組件
組件 |
說明 |
驗證器 |
處理原生和其它通用類型?;掘炞C器包括required,mask(匹配正則表達(dá)式),minLength,maxLength,range,nativetypes, date,email,和creditCard。也可以定義定制 (或者插件) 驗證器。 |
資源文件 |
提供(本地化的)標(biāo)注和消息。默認(rèn)與Struts 共享消息資源。 |
XML 配置文件 |
根據(jù)需要定義針對字段的表單集和驗證。驗證器可以在一個單獨的文件中定義。 |
JSP 標(biāo)簽 |
對給定的表單或Action 路徑產(chǎn)生JavaScript 驗證器。 |
ValidatorForm |
根據(jù)FormBean 的名稱自動驗證屬性(在運行時通過ActionMapping 參數(shù)傳到validate 方法)。必須被擴展才能提供表單之上的期望屬性的驗證。 |
ValidatorActionForm |
基于action 路徑自動驗證屬性(在運行時通過ActionMapping參數(shù)傳到validate 方法)。必須被擴展才能提供表單之上的期望屬性的驗證。 |
有些字段可能必須要求有數(shù)據(jù)輸入。而郵政編碼總是具有已知的長度。其它公共字段類型包括數(shù)值、日期、身份證號碼等等。
驗證器本身具有一些基本的驗證器來處理這些公共需要,當(dāng)然還有其它一些需要。如果你的驗證不能被基本驗證器或者正則表達(dá)式滿足,你可以開發(fā)你自己的驗證器并插入到包中。基本驗證器支持其自身附帶的基本插件。
安裝和配置
Validator框架采用兩個基于XML的配置文件來配置驗證規(guī)則。一個是validator-rules.xml,另一個是validation.xml,這兩個文件應(yīng)該部署在對應(yīng)于WEB應(yīng)用程序的WEB-INF文件夾下,對應(yīng)的兩個jar文件也添加到WEB-INF/lib目錄下。
1、 validation-rules.xml
在validation-rules.xml 文件中配置了一些全局性的驗證規(guī)則,使得你在應(yīng)用程序中使用校驗而不用關(guān)注實現(xiàn)細(xì)節(jié)。這個配置文件是Validator 框架自帶的,可以用在所有Struts應(yīng)用中。它默認(rèn)配置了許多很常用的規(guī)則,一般來說,不用去更改它,除非需要擴展或修改這些默認(rèn)的驗證規(guī)則。
建議:即使你需要擴展一些規(guī)則,也不要去修改validation-rules.xml,而是通過新的配置文件去定義你所擴展的校驗規(guī)則。
validator-rules.xml文件的根元素是form-validation,它包含一到多個global元素,global元素包含一到多個validator 元素。
每一個validator 元素定義了一個唯一的驗證規(guī)則。下面是validation-rules.xml 文件中的一個片斷, (mask)驗證規(guī)則:
<validator name="mask"
classname="org.apache.struts.validator.FieldChecks"
method="validateMask"
methodParams="java.lang.Object,
org.apache.commons.validator.ValidatorAction,
org.apache.commons.validator.Field,
org.apache.struts.action.ActionMessages,
org.apache.commons.validator.Validator,
javax.servlet.http.HttpServletRequest"
depends=""
msg="errors.invalid"/>
1) name: 賦予驗證規(guī)則的一個唯一的名稱。
2) classname: 指的是具體實現(xiàn)驗證規(guī)則的類。
3) method: 指包含具體實現(xiàn)類的方法。
4) methodParams: 聲明method屬性所指定的方法參數(shù),多個參數(shù)之間用逗號分隔。
5) depends: 指定在調(diào)用當(dāng)前的嚴(yán)整規(guī)則之前必須先調(diào)用的其他驗證規(guī)則。多個則用逗號分隔。
6) msg: 指定來自于Resource Bundle中的消息key。當(dāng)驗證失敗時,validator框架根據(jù)這個消息key到Resource Boundle中查找匹配的消息。
2、 validation.xml
Validator框架所需要的第二個配置文件是validation.xml,這個配置文件是具體應(yīng)用(項目)所特定的,可以根據(jù)你的應(yīng)用(項目)情況進行自定義配置。它描述了具體的ActionForm使用validation-rules.xml文件中的哪個驗證規(guī)則進行驗證。
一個自定義的驗證規(guī)則如下:
<form-validation>
<formset>
<form name="loginActionForm">
<field property="username" depends="required">
<arg key="label.username" />
</field>
<field property="userpass" depends="required">
<arg key="label.password" />
</field>
</form>
</formset>
</form-validation>
Validator.xml文件的根元素為<form-validation>元素,它包含兩個子元素:<global>和<formset>元素。
1) <global>元素可以定義<constant>子元素,它用來定義常量表達(dá)式。
2) <formset>元素包含兩個子元素:<contant>和<form>。
3) <form>元素用于為表單配置驗證規(guī)則,它的name屬性表示你驗證formBean,必須和struts-config.xml里面FormBean名字保持一致。<form>元素可以包含一個或多個<field>子元素。
4) <field>元素是針對表單中字段的驗證規(guī)則。Property屬性用于指定FormBean中需要驗證的字段的名稱,depends屬性用于指定字段的驗證規(guī)則,多個用逗號分隔。
5) <arg>元素表示出錯時的主體信息,key 是你屬性文件里面的key。
6) 主要是對前面<depends>元素包含的驗證規(guī)則的定義。
3、插入Validator
每一個Struts應(yīng)用需要知道是否使用了Validator框架,可以通過PlugIn(插件)機制將Validator框架配置到Struts應(yīng)用中。
下面的代碼演示了如何將Validator 作為一個插件加入到Struts 應(yīng)用中,在Struts 應(yīng)用的配置文件Struts-config.xml 中加入如下代碼片段:
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validator.xml"/>
</plug-in>
pathnames屬性的值用來指定Validator 框架所使用的配置文件,多個配置文件之間用逗號分隔。
當(dāng)應(yīng)用啟動的時候,Struts框架將調(diào)用ValidatorPlugIn的init()方法。Validator框架的配置文件將會加載到內(nèi)存中供應(yīng)用使用。在init()方法被調(diào)用之前,pathnames所指定的值將會傳遞給ValidatorPlugIn的實例,ValidatorPlugIn實例將會依據(jù)這個值去加載配置文件。
案例說明:根據(jù)前面的例子我們進行進階,要求用戶輸入用戶名、密碼。并且用戶名、密碼是必須,若為空,則提示錯誤信息。
A、服務(wù)器段驗證
1、修改FormBean
我們以前的是繼承ActionForm,現(xiàn)在改成ValidatorForm,導(dǎo)入相應(yīng)的包,并刪除validator和reset方法。
2、修改struts-config.xml文件,具體代碼如下:
<action
path="/login"
name="loginActionForm"
scope="request"
type="org.zhoudq.webapp.action.LoginAction"
validate="true"
input="/login.jsp">
<forward name="success" path="/success.jsp" />
<forward name="error" path="/wrong.jsp" />
</action>
將validator改為true,告訴服務(wù)器對這個表單進行驗證,input的值,是告訴服務(wù)器如果嚴(yán)整失敗的話,將跳轉(zhuǎn)的頁面。
3、添加驗證規(guī)則
在WEB-INF下創(chuàng)建validaton.xml這個文件,導(dǎo)入引用的dtd,添加如下內(nèi)容:
<form-validation>
<formset>
<form name="loginActionForm">
<field property="username" depends="required">
<arg key="label.username" />
</field>
<field property="userpass" depends="required">
<arg key="label.password" />
</field>
</form>
</formset>
</form-validation>
3、修改Resource Boundle文件:
英文的資源文件:applicationResource_en_US.properties
errors.required={0} is required.
errors.minlength={0} can not be less than {1} characters.
errors.maxlength={0} can not be greater than {1} characters.
errors.invalid={0} is invalid.
errors.byte={0} must be a byte.
errors.short={0} must be a short.
errors.integer={0} must be an integer.
errors.long={0} must be a long.
errors.float={0} must be a float.
errors.double={0} must be a double.
errors.date={0} is not a date.
errors.range={0} is not in the range {1} through {2}
errors.creditcard={0} is an invalid credit card number.
errors.email={0} is an invalid e-mail address.
button.submit=Submit
button.reset=Reset
button.cancel=Cancel
label.username=UserName:
label.password=Password:
loginform.error.username=please enter your username
loginform.error.password=please enter your password
loginform.fail=invalidation name and password,login error!
中文的資源文件:applicationResource_zh_CN.properties
errors.required={0} 是必須的.
errors.minlength={0} 不能少于 {1} 個字符.
errors.maxlength={0} 不能多于 {1} 個字符.
errors.invalid={0} 是非法的.
errors.byte={0} 必須是 byte 類型.
errors.short={0} 必須是 short 類型.
errors.integer={0} 必須是 Integer 類型.
errors.long={0} 必須是 long 類型.
errors.float={0} 必須是 float 類型.
errors.double={0} 必須是 double 類型.
errors.date={0} 不是一個日期.
errors.range={0} 不在 {1}- {2} 之間.
errors.creditcard={0} 是一個非法的身份證號r.
errors.email={0} 是一個非法的油箱地址.
button.submit=確定
button.reset=重置
button.cancel=取消
label.username=用戶名:
label.password=密碼:
loginform.error.username=請輸入用戶名
loginform.error.password=請輸入密碼
loginform.fail=用戶名或密碼錯誤,登錄失敗!
5、在struts-config.xml添加validator
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validator.xml"/>
</plug-in>
5、運行
打開IE,鍵入:http://localhost:8080/Struts1_Login/login.jsp,直接點確定,如下圖:
B、客戶端驗證
這也表現(xiàn)了Validator驗證框架的強大之處,又服務(wù)器生成javascript腳本,這樣就直接在客戶端進行驗證了,從而減少了服務(wù)器的壓力,萬事有力又有避,這中方式服務(wù)器在生成腳本的同時又犧牲能性能,呵呵,看如何實現(xiàn)吧,一定很振奮吧.
1) 修改login.jsp頁面
<%@ page contentType="text/html; charset=GBK"%>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<html:html>
<head><title>login</title></head>
<body bgcolor="#ffffff">
<h1>login</h1>
<div>
<font color="red">
<html:messages id="error">
<li><bean:write name="error"/></li>
</html:messages>
</font>
</div>
<html:javascript formName="loginActionForm" />
<html:form action="login.do" onsubmit="return validateLoginActionForm(this);">
<bean:message key="label.username"/>
<html:text property="username" />
<br />
<bean:message key="label.password"/>
<html:text property="userpass" />
<br>
<html:submit property="submit"><bean:message key="button.submit"/></html:submit>
<html:reset><bean:message key="button.reset"/></html:reset>
</html:form>
</body>
</html:html>
a)<html:javascript formName="loginActionForm" />表示生成js代碼,formName屬性指定驗證表單的名字,必須和struts-config.xml里面的form一樣。
b)<html:form action="login.do" onsubmit="return validateLoginActionForm(this);">
當(dāng)用戶提交表單的時候,就會調(diào)用<html:javascript>標(biāo)簽生成的javascript腳本的方法,從而執(zhí)行客戶端的驗證,其中的LoginActionForm是你FormBean的名字對用,必須和struts-config.xml里面的form一樣,在這里面第一個字母大寫哦。
2)運行測試:
打開IE,鍵入:http://localhost:8080/Struts1_Login/login.jsp,直接點確定,如下圖:
簡單嗎?嘿嘿,兩步就搞定了吧。希望大家繼續(xù)關(guān)注我哦。
一、概念
I18N作為“國際化”的簡稱,其來源是明文單詞“internationlization”的首末字符“i”和“n”之間的字符數(shù)為18。隨著全球經(jīng)濟的遺體化為一種主流的趨勢,軟件開發(fā)者應(yīng)該開發(fā)出支持多國語言、國家化的web應(yīng)用程序吧。也就是一個web應(yīng)用程序在運行時能夠根據(jù)客戶端請求所來自的國家和語言的不同顯示不同的用戶界面。這樣,當(dāng)需要在應(yīng)用程序中添加對一種新的語言的支持時,不需要對已有的軟件返工,無需修改應(yīng)用程序的程序代碼。
二、Struts對國家化的支持
在Struts框架中進行應(yīng)用程序的國際化,支持重點在于應(yīng)用程序的文本和圖像表示。最重要的工作就是準(zhǔn)備Resurce Bundle 資源包。事實上,準(zhǔn)備資源包的過程,就是把對應(yīng)不同語言的用戶所涉及的文本和圖片保存在多個文本文件中,客戶端根據(jù)不同的環(huán)境需要進行更換。這些文件被稱為“屬性文件”,所有屬性文件合在一起被稱為資源包(Resource Bundle)。
Struts建立于Java平臺之上,很容易建立國際化和本地化的應(yīng)用程序。在這里你要熟悉的關(guān)鍵概念是:
1) Locale – 基礎(chǔ)的支持國際化的java類是java.util.Locale。每個Locale代表一個特別的國家和語言的選擇(加上一個可選的語言變量),以及一套格式假定,例如數(shù)字和日期等等。
2) ResourceBundle – java.util.ResourceBundle類提供支持多種語言消息的基本工具。查看文檔中關(guān)于ResourceBundle類以及你的JDK版本的文檔包中關(guān)于國際化的更多內(nèi)容。
3) PropertyResourceBundle – 一個ResourceBundle類的標(biāo)準(zhǔn)實現(xiàn)允許你使用與初始化properties文件同樣的鍵/值的語法來定義資源。這對于使用為用于一個web應(yīng)用程序的消息準(zhǔn)備資源包是非常方便的,因為這寫消息通常都是面向文本的。
4) MessageFormat – java.text.MessageFormat類允許你使用運行時的指定的參數(shù)替換一個消息字符串中的一部分(在這種情況下,是一個從一個資源包得到的消息)。這在你創(chuàng)建一個句子的場合中是有用的,但是詞會以不同的語言安照不同的順序出現(xiàn)。消息中的占位符,字符串{0}用第一個運行時參數(shù)替換,{1}用第二個運行時參數(shù)替換,以此類推。
5) MessageResources – Struts的類org.apache.struts.util.MessageResources使你能夠?qū)⒁惶踪Y源包視做一個數(shù)據(jù)庫,并且允許你為一個特定的Locale(通常是與當(dāng)前用戶相對應(yīng))請求一個特定的消息,而不是為服務(wù)器運行在其中的缺省的Locale請求消息。
三、示例
1、我們還在前面的登錄實例進行加工。
2、在默認(rèn)的applicationResources.properties文件中添加相應(yīng)的消息文本。
label.username=username
label.password=password
button.submit=submit
button.reset=reset
3、創(chuàng)建臨時中文資源文件:applicationResources_temp.propertyies
label.username=用戶名
label.password=密碼
button.submit=確定
button.reset=重置
4、對臨時資源文件進行編碼轉(zhuǎn)換:
在JDK中提供了native2ascii命令,它能夠?qū)崿F(xiàn)字符編碼轉(zhuǎn)換。在DOS下執(zhí)行以下命令,將生成按GBK以編碼的中文資源文件:applicationResources_zh_CN.properties
native2ascii –encoding gbk applicationResources_temp.properties
applicationResources_zh_CN.properties
生成的applicationResources_zh_CN.properties的內(nèi)容如下:
label.username="u7528"u6237"u540d
label.password="u5bc6"u7801
button.submit="u786e"u5b9a
button.reset="u91cd"u7f6e
當(dāng)web用戶的Locale為中文時,Struts框架將自動選擇來自applicationResources_zh_CN.properties文件的消息文本。
5、創(chuàng)建英文的資源文件:
label.username=username
label.password=password
button.submit=submit
button.reset=reset
完成以上幾個步驟后,在web 應(yīng)用程序的根目錄"WEB-INF目錄"classes目錄下應(yīng)該有了三個資源文件:
默認(rèn)資源文件:applicationResource.properties
中文資源文件:applicationResource_zh_CN.properties
英文資源文件:applicationResource_en.properties
6、創(chuàng)建struts的Resource Bundle
Struts配置文件中的<message-resources>元素定義了一個Resource Bundle。Resource Bundle的持久化消息文本存儲在資源文件中,其擴展名為“.properties”,里面存放的都是“鍵/值”。
在struts-config.xml中對Resource Bundle的配置代碼:
<message-resources parameter=”ApplicationResources”/>
表示默認(rèn)的資源文件應(yīng)該是applicationResources.properties,存放在應(yīng)用程序的根目錄"WEB-INF目錄"classes目錄下。如果應(yīng)用程序需要支持中文用戶,要在相同目錄下創(chuàng)建一個包涵中文消息的資源文件,文件名必須為applicationResource_zh_CN.properties。
7、修改login.jsp頁面
<html:form action="login.do" method="post">
<bean:message key="label.username"/>
<html:text property="username" /><html:errors property="username"/>
<br />
<bean:message key="label.password"/>
<html:text property="userpass" /><html:errors property="userpass"/>
<br>
<input type="submit" name="Submit" value="<bean:message key="button.submit"/>">
<input type="reset" value="<bean:message key="button.reset"/>">
</html:form>
<bean:message/>:用于訪問web應(yīng)用資源的bean標(biāo)簽,顯示Resource Boundle中的內(nèi)容。
8、運行程序
1)如果你的瀏覽器默認(rèn)設(shè)置為中文,你鍵入地址,將看到的頁面如下:
2)把你的瀏覽器的設(shè)置為英文,然后刷新頁面,如下圖:
總結(jié):國際化對于web應(yīng)用程序來說很重要,如果你的web應(yīng)用程序面對多個國家的話,要實現(xiàn)不同語言的切換,如果不使用國際化的話要么只有一種語言,要么在程序里面改,現(xiàn)在一切都方面了,不過java對中文的支持并不好,并不是什么地方都可以使用中文的,如在LookUpDispatchAction中就不能使用國際化哦。
請關(guān)注本人csdn:http://blog.csdn.net/xmh517/
效果圖:
我們以結(jié)果為導(dǎo)向,首先大家先看看要完成的效果圖,對接下來要做的事情有個清晰的認(rèn)識。
1、如圖鍵入:
顯示結(jié)果如下圖:
如果您輸入的是不合法的話,則如下圖:
修改步驟:
A、數(shù)據(jù)源配置
在struts-config.xml文件中有一<data-sources>元素是用來配置應(yīng)用所需要的數(shù)據(jù)源,數(shù)據(jù)源負(fù)責(zé)建立和特定數(shù)據(jù)庫的連接,許多數(shù)據(jù)源采用連接池的機制實現(xiàn),即提高了數(shù)據(jù)庫的訪問性能。具體代碼片段如下所示:
<data-sources>
<data-source key="DataSource" type="org.apache.commons.dbcp.BasicDataSource">
<set-property property="driverClassName" value="com.mysql.jdbc.Driver" />
<set-property property="url" value="jdbc:mysql://localhost:3306/struts1_login"/>
<set-property property="username" value="root"/>
<set-property property="password" value="5ihpp1314"/>
</data-source>
</data-sources>
上面這段代碼配置了與MySQL數(shù)據(jù)庫的連接。<data-source>元素的key是一個別名,用于在應(yīng)用程序中去的一個連接,元素type用來指定數(shù)據(jù)源的實現(xiàn)類。上面使用的是Apache軟件組織提供的DBCP數(shù)據(jù)源。所以你必須導(dǎo)入commons-dbcp.jar、commons-pool.ar、struts-legacy..jar這三個包和MySQL的驅(qū)動包:mysql-connector-java-5.0.5-bin.jar。
配置了數(shù)據(jù)源后,就可以在Action中訪問數(shù)據(jù)源了。
代碼如下所示:
//獲取Servlet上下文對象
ServletContext ctx = servlet.getServletContext();
//獲得數(shù)據(jù)源
DataSource ds = (DataSource) ctx.getAttribute("DataSource");
//獲取數(shù)據(jù)庫的連接
Connection conn = ds.getConnection();
B、修改Action
Action將取得數(shù)據(jù)源,得到一個數(shù)據(jù)庫的連接,把頁面?zhèn)鹘鼇淼挠脩裘兔艽a,通過jdbc與數(shù)據(jù)庫進行對比,如果存在轉(zhuǎn)到“success.jsp”并顯示其名稱,否則到錯誤頁面。
具體實現(xiàn)代碼如下所示:
public class LoginAction extends Action {
public ActionForward execute(ActionMapping actionMapping,
ActionForm actionForm, HttpServletRequest request,
HttpServletResponse response) {
LoginActionForm loginform = (LoginActionForm) actionForm;
String username = loginform.getUsername();
String userpass = loginform.getUserpass();
ServletContext ctx = servlet.getServletContext();
DataSource ds = (DataSource) ctx.getAttribute("DataSource");
boolean flag = false;
String sql = "select * from user where username='" + username
+ "' and password='" + userpass + "'";
try {
Connection conn = ds.getConnection();
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
while (rs.next()) {
flag = true;
}
} catch (Exception e) {
e.printStackTrace();
}
String actionpath = "";
if (flag) {
request.setAttribute("username", username);
actionpath = "success";
} else {
actionpath = "error";
}
return actionMapping.findForward(actionpath);
}
}
C、修改頁面
如果登錄成功,通過EL顯示用戶名。
具體代碼如下:
<%@ page contentType="text/html; charset=GBK" %>
<%@taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<html>
<head>
<title>
success
</title>
</head>
<body bgcolor="#ffffff">
<h1>success.jsp demo</h1>
<br>
<h1>welcome
<font color="red" size="8"><bean:write name="username"/></font>
here,thanks
</h1>
</body>
</html>
引入struts的標(biāo)簽,輸出用戶名稱。
小結(jié):怎么樣出來你要的結(jié)果了吧,不過是使用的數(shù)據(jù)源配置,我個人認(rèn)為讓struts來管理不是太妥當(dāng),因為數(shù)據(jù)的相關(guān)操作應(yīng)該屬于持久層的管理,不應(yīng)該由上一層管理(Controller),所以實際操作中建議不要這么做。
在進行web應(yīng)用程序開發(fā)的過程中,中文問題經(jīng)常困擾著很多程序員。因此,在接下來的兩個課程的學(xué)習(xí)中,我將根據(jù)實踐經(jīng)驗來談一下web應(yīng)用中的中文問題的解決方法。讓大家不再為此而頭痛。
我們就前那個登錄驗證的例子,進行進階,處理中文亂碼問題。前面例子中,只要用戶名和密碼都是123,才返回成功的頁面。為了處理中文,我們判斷只有用戶名是張三才登陸成功。
一、程序進階:
既然是中文亂碼處理,頁面的用戶輸入就是中文了,相應(yīng)的action的if處理也要變成: if (username.equals("張三") && userpass.equals("123"));
效果圖:
我們以結(jié)果為導(dǎo)向,首先大家先看看要完成的效果圖,對接下來要做的事情有個清晰的認(rèn)識。
1、如圖鍵入:中文
顯示結(jié)果如下圖:
為什么會到錯誤頁面呢?我們明明都寫正確了呀,是的,沒有錯誤,這是什么原因呢?
請看下圖:
我們打印才發(fā)現(xiàn)原來username的值傳到action中,成了亂碼,這主要由于客戶端和服務(wù)器端采用了不同的字符集,中文亂碼我們沒有處理。
二、解決辦法:
A、直接轉(zhuǎn)編碼
我們新建一個包,命名為util,在包下新建一個類文件,命名為EncodingUtil,類的功能就是提供一個字符集轉(zhuǎn)換的一個方法,具體代碼如下所示:
package util;
public class Encoding {
public static String isToGB(String src) {
String strRet = null;
try {
strRet = new String(src.getBytes("ISO_8859_1"), "GBK");
} catch (Exception e) {
e.printStackTrace();
}
return strRet;
}
}
小結(jié):這辦法雖然能解決中文亂碼,但是每次還得調(diào)用,是不是很不方便呢?如果忘記了調(diào)用這個方法,那程序又亂碼了,維護起來很困難,下面我們看另一種解決方案。
B、繼承RequestProcessor類
RequestProcessor類處理ActionServlet接收到的所有請求。根據(jù)它的處理方式,可將每個請求分解為多個小任務(wù),分別由不同的方法執(zhí)行。這就允許針對請求的各個單獨部分自定義處理。
RequestProcessor類的部分方法如下:
processPath(): 獲取客戶端請求的路徑URI
processMapping(): 根據(jù)請求URI獲取所需的映射信息
processRoles(): 檢查用戶的角色是否允許他訪問請求的資源
processActionForm(): 新建一個Form Bean或從請求會話中檢索Form Bean
processForward(): 處理<action-mapping>元素forward以匹配當(dāng)前的請求路徑
processValidate(): 調(diào)用Form Bean的validate()方法
processPreprocess(): 告訴請求處理器調(diào)用此方法后,是否應(yīng)繼續(xù)處理請求
processLocale(): 為請求選擇一個語言環(huán)境
processActionCreate(): 實例化當(dāng)前ActionMapping指定的類的實例
processActionPerform(): 將調(diào)用action的perform()或execute()方法
呵呵,發(fā)沒發(fā)現(xiàn)RequestProcess類的所有方法都有一個前綴proess,接著往下看吧。
RequestProcessor在action之前,所以我們應(yīng)著手RequestProcessor,要開發(fā)自己的RequestProcessor類,步驟如下:
(1) 創(chuàng)建一個繼承org.apache.struts.action.RequestProcessor的類,在改類中顯示定義一個無參,方法體為空的構(gòu)造器。
(2) 重寫所需的方法,加入我們的功能。
具體代碼如下所示:
package servlets;
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.RequestProcessor;
public class EncodingHandler extends RequestProcessor {
public boolean processPreprocess(HttpServletRequest servletRequest,
HttpServletResponse serveltResponse) {
try {
servletRequest.setCharacterEncoding("GBK");
System.out.println("請求被處理.");
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
}
return true;
}
}
(3) 修改配置文件sturts-config.xml,在其中加入一個名為<controller>的元素,用以指定我們定制的RequestProcessor類。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<form-beans>
<form-bean name="loginActionForm" type="formbeans.LoginActionForm" />
</form-beans>
<action-mappings>
<action
path="/login"
name="loginActionForm"
scope="request"
type="actions.LoginAction">
<forward name="success" path="/success.jsp"/>
<forward name="error" path="/wrong.jsp"/>
</action>
</action-mappings>
<controller processorClass="servlets.EncodingHandler" />
</struts-config>
上面就是我們自己的定義的RequestProcessor類,使用<controller>標(biāo)簽類定義。
如圖:
小結(jié):這樣做呢?問題是解決了,每一個請求先經(jīng)過這個方法,并轉(zhuǎn)換了字符集再交給action做處理,這樣我們不用在操心中文亂碼,但RequestProcessor是與struts耦合在一塊兒。如果不用struts框架,我們又該如何處理中文問題呢?是否又更好的辦法呢?那就接著跟我往下看吧。
C、Filter來解決中文問題
Filter,是不是你腦子里閃現(xiàn)了這個詞呢?下面就來看看如何用它來改寫我們上一章節(jié)的例子吧!
(1) 首先在工程中新建一包,命名為filter,在下面新建一類文件,命名為EncodingServlet,并繼承HttpServlet、實現(xiàn)Filter接口,注意并實現(xiàn)接口的方法。
在Servlet中filter起著過濾器的作用,當(dāng)一個請求發(fā)送到服務(wù)器的時候,需要把請求首先交給filter來處理,然后交給action做處理。EncodingServlet負(fù)責(zé)處理請求的字符集,在此就起這么個功能,具體代碼請依照如下所示:
package servlets;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
public class EncodingServlet extends HttpServlet implements Filter {
private static final long serialVersionUID = 1L;
public void doFilter(ServletRequest servletRequest,
ServletResponse serveltResponse, FilterChain filterChain) {
try {
servletRequest.setCharacterEncoding("GBK");
filterChain.doFilter(servletRequest, serveltResponse);
} catch (Exception ex) {
}
}
public void init(FilterConfig arg0) throws ServletException {
}
}
(2) 修改web.xml,加入我們的filter。
<filter>
<filter-name>EncodingServlet</filter-name>
<filter-class>servlets.EncodingServlet</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingServlet</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
小結(jié):這個中文亂碼處理用了fileter,而且適用與任何場合,比較實用。
怎么樣,通過三個處理中文亂碼的方案,有和感想呀,是不是程序很有意思呀,那就跟著我繼續(xù)看看struts別的東東吧……
請關(guān)注本人csdn:http://blog.csdn.net/xmh517/
Struts是一個基于Sun J2EE平臺的MVC框架,主要是采用Servlet和JSP技術(shù)來實現(xiàn)的。由于Struts能充分滿足應(yīng)用開發(fā)的需求,簡單易用,敏捷迅速,在過去的幾年中頗受關(guān)注。Struts把Servlet、JSP、自定義標(biāo)簽和信息資源(message resources)整合到一個統(tǒng)一的框架中,開發(fā)人員利用其進行開發(fā)時不用再自己編碼實現(xiàn)全套MVC模式,極大的節(jié)省了時間,所以說Struts是一個非常不錯的應(yīng)用框架。很多公司開發(fā)的產(chǎn)品都是基于此框架的。
當(dāng)然,有朋友一提起編程就覺得頭痛,是否如此呢?我想通過本期的struts教程,你便會有自己的結(jié)論喲!
本期struts教程本著從易用、實用的目的出發(fā),帶您手把手地完成公司開發(fā)中常用模塊的開發(fā),使你迅速上手struts。
主要通過以下六個模塊:
一、登錄驗證實例
二、解決中文亂碼問題實例
三、連數(shù)據(jù)庫實例
四、國際化
五、驗證數(shù)據(jù)實例
六、模塊使用實例
七、制作簡單留言板實例
使大家對struts能由淺入深的學(xué)習(xí),最終撐握它。
萬事開頭難,就讓我們一起來經(jīng)歷struts的開發(fā)吧,經(jīng)過本系列的學(xué)習(xí),你肯定能很快地駕馭它。給自己多幾分信心吧!
閑話不多說,接下來就開始實戰(zhàn)吧??!
一、普通的登錄驗證實例
效果圖:
我們以結(jié)果為導(dǎo)向,首先大家先看看要完成的效果圖,對接下來要做的事情有個清晰的認(rèn)識。
1、如圖鍵入:
顯示結(jié)果如下圖:
如果您輸入的是合法的話,則如下圖:
開發(fā)步驟:
A、首先建立一工程,選擇web模塊,最后再加載struts包即可。在工程中新建一包,命名為actions,在下面新建一類文件,命名為LoginAction,里面一定要重寫execute方法,注意參數(shù)的順序及返回類型都是不可以變化的。
在struts中action類起著控制轉(zhuǎn)向的作用,當(dāng)我們輸入用戶名與密碼并點了提交按鈕后,需要交給控制器來決斷我們是轉(zhuǎn)向到登陸成功頁還是登陸失敗頁。LoginAction在此就起這么個功能,具體代碼請依照如下所示:
public class LoginAction extends Action {
public ActionForward execute(ActionMapping actionMapping,
ActionForm actionForm,
HttpServletRequest servletRequest,
HttpServletResponse serveltResponse) {
LoginActionForm loginform = (LoginActionForm) actionForm;
String username = loginform.getUsername();
String userpass = loginform.getUserpass();
boolean flag = false;
String actionpath = "";
if (username.equals("123") && userpass.equals("123")) {
actionpath = "success";
} else {
actionpath = "error";
}
return actionMapping.findForward(actionpath);
}
}
在“LoginAction”中,我們得到一個ActionForm對象,并把它強轉(zhuǎn)成LoginActionForm,
待我們處理,即通過ActionForm的匹配名稱的表單自動封裝機制,取得用戶輸入用戶名、密碼。
我們返回的結(jié)果將會被ActionFormward對象所包裝,比如這兒的“success“表示用戶合法,“error”表示用戶不合法,這個字符串將決定著頁面的流程控制。它并不是一個具體存在的頁面,它是如何跟一個具體的頁面關(guān)聯(lián)上的呢?
呵呵,先不要急,我們來分析幾點:
1、 你在操作時記住的概念:
Struts的核心是Action,而Action的核心就是一個配置文件——struts-config.xml。它既然是核心就很重要哦。
2、 Maping映射:
a) actionMapping.findForward(“映射名稱”); 它返回的是一個ActionForward對象
b) struts-config.xml里面action節(jié)點下的:<forward name="映射名稱" path="/頁面名稱"/>
實現(xiàn)機制:Struts會根據(jù)你傳進actionMapping.findForward(“映射名稱”),它會到你當(dāng)前action節(jié)點下去找forward這個節(jié)點,并把你傳進的參數(shù)與這個節(jié)點的name屬性進行匹配。如果相等它就會跳到這個節(jié)點的path所指定的頁面。
例:
Action:actionMapping.findForward(“success”)
Struts-config.xml:<forward name="success" path="/success.jsp"/>
如果是這種情況的話,它就會轉(zhuǎn)發(fā)到success.jsp頁面。
注意:
a) 方法的參數(shù)值和name節(jié)點的值對應(yīng),
b) Path所指定的頁面,前面必須加上“/“
B、在前面我們提到了ActionForm,所以我們還需要建立一個類文件,這個類文件將封裝頁面用戶輸入的用戶名、和密碼。
注意:
1、這個類必須繼承ActionForm類,它將完成與頁面的自動封裝。
2、類中的屬性名稱一定要和頁面的輸入框的名稱對應(yīng),為了自動封裝的匹配工作。
3、這個類中一定要提供所有與屬性相匹配的set 和 get方法。
好,前面寫了這些代碼,看上去還是有些雜亂無章,怎么把它們關(guān)聯(lián)起來呢?又怎么調(diào)用這些代碼呢?呵呵,群龍不會無首的,下面就一起來關(guān)注struts的裝配文件,它可是相當(dāng)于struts的總司令喲!
C、核心部分,跳轉(zhuǎn)控制Struts-config.xml部分
<struts-config>
<form-beans>
<form-bean name="loginActionForm" type="formbeans.LoginActionForm" />
</form-beans>
<action-mappings>
<action path="/login" name="loginActionForm" type="actions.LoginAction">
<forward name="success" path="/success.jsp"/>
<forward name="error" path="/wrong.jsp"/>
</action>
</action-mappings>
</struts-config>
我們對struts.xml做一下相應(yīng)的介紹吧,如下:
<form-bean>:用來配置一個ActionForm Bean。常用配置的幾個屬性:
name:指定該ActionForm Bean的唯一標(biāo)識符,整個Struts框架用該標(biāo)識符來引用這個Bean。該屬性是必需的
type:指定ActionForm類的全限定名。該屬性是必需的
<action>:用來描述特定的請求路徑到相應(yīng)的Action類的映射。常用配置的幾個屬性:
input: 指定包含輸入表單的URL路徑。當(dāng)表單驗證失敗時,將把請求轉(zhuǎn)發(fā)到該URL。
name: 指定和該Action關(guān)聯(lián)的ActionForm Bean的名字。
path: 指定訪問Action的路徑,它以“/”開頭,沒有擴展名。
Scope: 指定ActionForm Bean的存在范圍。(session | request)
Validate:指定是否要先調(diào)用ActionForm Bean的validate()方法。默認(rèn)值為true
Action的子元素<forward>常用配置的幾個屬性:
name: 指定轉(zhuǎn)發(fā)路徑的邏輯名。必需的
path: 指定轉(zhuǎn)發(fā)(或重定向)的URI,必須以”/”開頭。必需的
redirect:當(dāng)此項為true時,表示執(zhí)行重定向操作。為false時表示執(zhí)行請求轉(zhuǎn)發(fā)操作。默認(rèn)值為false
D、頁面login.jsp,用戶登錄頁面,提供用戶輸入功能。具體代碼如下所示:
<form method="post" action="login.do">
請輸入姓名:<input type="text" name="username" value=""/><br />
請輸入密碼:<input type="password" name="userpass" value=""/><br>
<input type="submit" name="Submit" value="Submit">
<input type="reset" value="Reset">
</form>
注意:
1、action后面的login.do就是struts-config.xml里面你要訪問的action節(jié)點path的值哦
2、切記哦,如果你請求的URL的引用了formbean的話,這里的名稱一定要對應(yīng)哦。
還有success.jsp 、wrong.jsp分別代表登錄成功和登錄失敗頁面。就不再多說啦!
啟動Tomcat,連接上您的應(yīng)用程序網(wǎng)址,例如:http://localhost:8080/Struts1_Login/login.jsp,填入用戶名、密碼,并送出窗體,您的歡迎頁面就會顯示了。
怎么樣,本章節(jié)是不是比較容易?其實struts就這么簡單,能完成本章節(jié)的要求吧!現(xiàn)在你已經(jīng)上手啦,接著往下學(xué),我們會有越來越多的收獲喲?。?br />
請關(guān)注本人csdn:http://blog.csdn.net/xmh517/