剛接觸Struts,剛接觸MVC架構(gòu),或者剛接觸任何新東西,我覺得首先要搞清楚流程,要對(duì)新事物有一個(gè)大概的、總體的認(rèn)識(shí),先有感性認(rèn)識(shí),先培養(yǎng)起來興趣是非常重要的。下面就把我學(xué)習(xí)Struts的總體業(yè)務(wù)流程通過一個(gè)實(shí)例來進(jìn)行概括,有什么錯(cuò)誤和不妥之處,請你發(fā)表評(píng)論指教!
(1)搭建環(huán)境
1、獲得struts的支持包。struts是apache開源基金組織的一個(gè)子項(xiàng)目,你可以從http://struts.apache.org/download.cgi 下載struts的source或者Binaries,目前最新版本是1.2.4。
2、使用Tomcat作為jsp/Servlet容器。本文使用Tomcat,如果沒有此軟件,請從http://jakarta.apache.org/tomcat/index.html 下載。
3、在Tomcat中建立站點(diǎn)(相當(dāng)于MS IIS虛擬目錄)。譬如下面的代碼在Tomcat中建立一個(gè)站點(diǎn)study,建好以后此站點(diǎn)的地址即為:http://127.0.0.1:8080/study 。Tomcat的全局配置文件server.xml位于安裝目錄的conf文件夾下。
<Context path="/study" docBase="g:\java\webapps" debug="0" crossContext="true" reloadable="true">
</Context>

4、在站點(diǎn)(絕對(duì)路徑)下創(chuàng)建web站點(diǎn)的目錄結(jié)構(gòu)。此步省略
5、將struts的支持包struts.jar拷貝到站點(diǎn)的lib目錄下,即g:\java\webapps\WEB-INF\lib;將struts的標(biāo)記庫描述文件拷貝到/WEB-INF/tag/目錄下,這個(gè)路徑和將來導(dǎo)入標(biāo)記庫有關(guān),在后面也有描述。
6、站點(diǎn)的配置文件web.xml;此步的目的是讓tomcat將*do的請求轉(zhuǎn)發(fā)到org.apache.struts.action.ActionServlet,然后讀入struts的配置文件struts-config.xml。配置信息如下:




















到此,前期配置工作基本完成,關(guān)于strus的配置文件struts-config.xml的使用和詳細(xì)信息,請見下一節(jié)。
上一節(jié)我們搭建了Struts的運(yùn)行和開發(fā)環(huán)境。這一節(jié)著重講述MVC的基本概念和與使用JSP/JavaBean模式開發(fā)Web應(yīng)用的比較。
(1)Tomcat的啟動(dòng)。
從上一節(jié)的Tomcat的配置文件中,我們可以看到關(guān)于Struts的配置,當(dāng)Tomcat啟動(dòng)時(shí),會(huì)加載Struts的配置文件struts-config.xml,關(guān)于配置文件的內(nèi)容請見
(2)JSP/JavaBean開發(fā)Web應(yīng)用
在asp的時(shí)代,我們還沒有討論什么開發(fā)模式,也沒有顧及MVC(雖然MVC的概念早已出現(xiàn))。用asp開發(fā)不外乎以下兩種情況,一、就是直接將代碼集成到asp文件中,經(jīng)驗(yàn)多的話,會(huì)將常用的函數(shù)放至一起,引用時(shí)只需include即可;二、對(duì)于復(fù)雜的應(yīng)用,如文件上傳等,我們會(huì)用其他語音如VB、Delphi等寫一個(gè)控件(ADO即屬于此類)。
當(dāng)java流行,JSP逐漸成熟,也正是模式、框架流行的時(shí)代,所以我們不管是看java的類庫,還是看現(xiàn)在流行的框架,無一沒有模式的存在。當(dāng)你初接觸JSP的時(shí)候,就可以看到書上說“盡量少的在jsp中插入Java代碼”,這句話已是模式運(yùn)用的端倪。
下面我們先不管MVC,先從JSP/JavaBean來看Web的開發(fā)。這種模式很想上面提到的asp開發(fā)的第二種情況,我們將業(yè)務(wù)邏輯放到JavaBean中,只用JSP去表示頁面。
有過asp經(jīng)驗(yàn)都知道,在接收表單數(shù)據(jù)的時(shí)候,我們不得不一個(gè)一個(gè)將數(shù)據(jù)接收過來,以至于有很長的一段如:CustomId = request("CustomId")的代碼。而在JSP中,我們不用這么繁瑣,一個(gè)我們可以用EL直接表示即可,另外我們可以利用javaBean的introspection機(jī)制。直接將表單的數(shù)據(jù)映射到j(luò)avabean的private變量中,當(dāng)然javabean中必須包含getter和setter函數(shù)(有很幸運(yùn),很多的開發(fā)工具可以自動(dòng)生成,又減少了工作量)。下面是一個(gè)示例。


(3)MVC模式
上面提到的JSP/JavaBean與MVC模式很接近,但是還有很多差別。前者,我們可以看出,在javabean中有很多的邏輯代碼,我們要控制頁面的跳轉(zhuǎn),還是要在JSP中讀取javabean中的某些標(biāo)志,嵌入java代碼來實(shí)現(xiàn),這看起來顯得有些笨拙。我們是否能在JSP和javabean中再加一層,專門來實(shí)現(xiàn)跳轉(zhuǎn)即控制頁面的輸出呢?of course,這就是MVC的思想。
Struts就是一個(gè)實(shí)現(xiàn)MVC模式的WEB開發(fā)框架,在Struts中用JSP作為Viewer,javabean繼承自ActionForm來映射JSP表單數(shù)據(jù),用繼承自Action的類來實(shí)現(xiàn)Controller,而Model沒有特殊定義,它可以是EJB,普通Bean或者Web服務(wù),總之Model中集成了業(yè)務(wù)邏輯的實(shí)現(xiàn),在Controller中去調(diào)用,完成后Controller控制顯示頁面(jsp文件)。
這樣一來,是不是業(yè)務(wù)流程非常的清晰?
下面我們付諸實(shí)踐,實(shí)現(xiàn)一個(gè)用戶注冊的簡單實(shí)例!
Struts學(xué)習(xí)心得之Struts流程篇(3) -示例
上一篇我們講了Struts的配置以及運(yùn)行環(huán)境,這一篇我們通過一個(gè)實(shí)例來說明Struts實(shí)現(xiàn)MVC的過程和Struts開發(fā)WEB應(yīng)用的一般方法。
(1)實(shí)例介紹
這是《論文在線提交》系統(tǒng)的用戶注冊部分,用戶填入用戶名(userid)和Email地址(email)后,如果Email和userid在數(shù)據(jù)庫中不存在,則注冊成功,將系統(tǒng)生成的8位密碼發(fā)送到用戶的信箱里。數(shù)據(jù)表定義如下:
CREATE TABLE passwd (
userid varchar(20) DEFAULT '' NOT NULL, #用戶id
password varchar(16) DEFAULT '' NOT NULL, #密碼 使用PASSWORD()加密后的
email varchar(50) DEFAULT '' NOT NULL, #email
PRIMARY KEY (userid),
KEY password (password)
);
(2)不使用MVC模式的實(shí)現(xiàn)
有過ASP設(shè)計(jì)經(jīng)驗(yàn)的開發(fā)人員,如果看到這樣一個(gè)功能,那簡直是太簡單了。只要設(shè)計(jì)一個(gè)表單,然后post給一個(gè)asp頁面,在這個(gè)頁面中實(shí)現(xiàn)數(shù)據(jù)檢查(檢查email和用戶名是否存在)及數(shù)據(jù)插入和email發(fā)送的功能。如果純用jsp實(shí)現(xiàn),基本流程也是一樣的。這樣做有什么不好呢?我們先看使用Struts的MVC來實(shí)現(xiàn)這樣的功能,然后我們再做一下比較。
(3)使用Struts MVC實(shí)現(xiàn)
如果使用框架,我們就必須按照框架進(jìn)行編程,而不是“自由”的編程,我們必須在實(shí)現(xiàn)中有M,有V、有C。下面看一下Struts實(shí)現(xiàn)MVC的一般流程。
i.
這是HTML中表單的定義,action指定要將表單中的數(shù)據(jù)提交給誰進(jìn)行處理,看以下幾種情況:1. 純用jsp,action肯定是一個(gè)jsp文件;2.使用jsp/JavaBean方式,action也是一個(gè)jsp,但是它將form中的數(shù)據(jù)映射到j(luò)avaBean中,然后在jsp文件中進(jìn)行獲取和處理;3. 采用MVC方式,這要轉(zhuǎn)變一下思路,腦子中要時(shí)刻清醒,M是什么,V是什么,C是什么,并且要理解它們的用途,不可用錯(cuò)和濫用。下面我們看一下Struts中MVC的表現(xiàn)方式和使用方法。
ii 首先我們看M、V和C的表現(xiàn)。在Struts中,
首先看viewer,這是表現(xiàn)層,主要有jsp、servelt和javabean組成。也就是說我們將表單的數(shù)據(jù)放到j(luò)avabean中,這個(gè)過程都是viewer的工作;
Controller,控制器主要是實(shí)現(xiàn)數(shù)據(jù)的驗(yàn)證,并且實(shí)現(xiàn)跳轉(zhuǎn),就是要將控制權(quán)交給“誰”。譬如:在用戶注冊中,當(dāng)用戶將數(shù)據(jù)傳到bean,然后到action時(shí),action去判斷email是否存在,如果存在將頁面跳轉(zhuǎn)到error.jsp或者輸出錯(cuò)誤信息,如果不存在就跳轉(zhuǎn)到注冊成功的頁面。
Model,這是業(yè)務(wù)邏輯,這在Struts中沒有強(qiáng)制定義,主要功能就是實(shí)現(xiàn)業(yè)務(wù)邏輯,是功能體,譬如實(shí)現(xiàn)數(shù)據(jù)庫的插入,刪除等。可以是POJO,也可以是EJB等。
(4)用Struts實(shí)現(xiàn)用戶注冊。
第一步、實(shí)現(xiàn)viewer,有以下幾個(gè)部分組成,signin.jsp(顯示輸入form和錯(cuò)誤顯示)、SignForm.java(一個(gè)javaBean,不過在Struts中要繼承自ActionForm,實(shí)現(xiàn)數(shù)據(jù)映射和簡單的驗(yàn)證)。一下是關(guān)鍵代碼:
signin.jsp
<font color=red>
<html:errors/> ---錯(cuò)誤處理 詳細(xì)信息見本blog《Struts中的錯(cuò)誤處理流程》
< SPAN>font>
<html:form action="/sign.do">
--- sign.do是一個(gè)Action,在解釋Struts-conf.xml時(shí)說明

<bean:message key="sign.userid"/><html:text property="userid"/><br>
<bean:message key="sign.email"/><html:text property="email"/>
<html:submit ><bean:message key="login.signup"/>< SPAN>html:submit>

< SPAN>html:form>

說明:<bean:message key="sign.userid"/>從資源文件中讀取數(shù)據(jù),詳細(xì)信息見本blog的《struts中資源文件的使用》
SignForm.java
從代碼我們可以看出,SignForm除了實(shí)現(xiàn)bean的getter和setter功能外還實(shí)現(xiàn)了簡單的驗(yàn)證,即驗(yàn)證userid和email是否為空,若空則出錯(cuò)!
關(guān)于form的action,我們在講action和編輯struts-config.xml文件時(shí)會(huì)進(jìn)行說明。
(1)實(shí)例介紹
這是《論文在線提交》系統(tǒng)的用戶注冊部分,用戶填入用戶名(userid)和Email地址(email)后,如果Email和userid在數(shù)據(jù)庫中不存在,則注冊成功,將系統(tǒng)生成的8位密碼發(fā)送到用戶的信箱里。數(shù)據(jù)表定義如下:







(2)不使用MVC模式的實(shí)現(xiàn)
有過ASP設(shè)計(jì)經(jīng)驗(yàn)的開發(fā)人員,如果看到這樣一個(gè)功能,那簡直是太簡單了。只要設(shè)計(jì)一個(gè)表單,然后post給一個(gè)asp頁面,在這個(gè)頁面中實(shí)現(xiàn)數(shù)據(jù)檢查(檢查email和用戶名是否存在)及數(shù)據(jù)插入和email發(fā)送的功能。如果純用jsp實(shí)現(xiàn),基本流程也是一樣的。這樣做有什么不好呢?我們先看使用Struts的MVC來實(shí)現(xiàn)這樣的功能,然后我們再做一下比較。
(3)使用Struts MVC實(shí)現(xiàn)
如果使用框架,我們就必須按照框架進(jìn)行編程,而不是“自由”的編程,我們必須在實(shí)現(xiàn)中有M,有V、有C。下面看一下Struts實(shí)現(xiàn)MVC的一般流程。
i.
ii 首先我們看M、V和C的表現(xiàn)。在Struts中,
首先看viewer,這是表現(xiàn)層,主要有jsp、servelt和javabean組成。也就是說我們將表單的數(shù)據(jù)放到j(luò)avabean中,這個(gè)過程都是viewer的工作;
Controller,控制器主要是實(shí)現(xiàn)數(shù)據(jù)的驗(yàn)證,并且實(shí)現(xiàn)跳轉(zhuǎn),就是要將控制權(quán)交給“誰”。譬如:在用戶注冊中,當(dāng)用戶將數(shù)據(jù)傳到bean,然后到action時(shí),action去判斷email是否存在,如果存在將頁面跳轉(zhuǎn)到error.jsp或者輸出錯(cuò)誤信息,如果不存在就跳轉(zhuǎn)到注冊成功的頁面。
Model,這是業(yè)務(wù)邏輯,這在Struts中沒有強(qiáng)制定義,主要功能就是實(shí)現(xiàn)業(yè)務(wù)邏輯,是功能體,譬如實(shí)現(xiàn)數(shù)據(jù)庫的插入,刪除等。可以是POJO,也可以是EJB等。
(4)用Struts實(shí)現(xiàn)用戶注冊。
第一步、實(shí)現(xiàn)viewer,有以下幾個(gè)部分組成,signin.jsp(顯示輸入form和錯(cuò)誤顯示)、SignForm.java(一個(gè)javaBean,不過在Struts中要繼承自ActionForm,實(shí)現(xiàn)數(shù)據(jù)映射和簡單的驗(yàn)證)。一下是關(guān)鍵代碼:
signin.jsp













1
package user;
2
3
import javax.servlet.http.HttpServletRequest;
4
5
import org.apache.struts.action.ActionError;
6
import org.apache.struts.action.ActionErrors;
7
import org.apache.struts.action.ActionForm;
8
import org.apache.struts.action.ActionMapping;
9
10
/**//**
11
* @author han
12
* @company soochow university
13
* 注冊bean
14
*/
15
public class SignForm extends ActionForm
{
16
private String userid = null;
17
private String email = null;
18
private String password = null;
19
20
21
/**//**
22
* @return Returns the password.
23
*/
24
public String getPassword()
{
25
return password;
26
}
27
/**//**
28
* @param password The password to set.
29
*/
30
public void setPassword(String password)
{
31
this.password = password;
32
}
33
/**//**
34
* @return Returns the email.
35
*/
36
public String getEmail()
{
37
return email;
38
}
39
/**//**
40
* @param email The email to set.
41
*/
42
public void setEmail(String email)
{
43
this.email = email;
44
}
45
/**//**
46
* @return Returns the userid.
47
*/
48
public String getUserid()
{
49
return userid;
50
}
51
/**//**
52
* @param userid The userid to set.
53
*/
54
public void setUserid(String userid)
{
55
this.userid = userid;
56
}
57
58
public void reset(ActionMapping mapping, HttpServletRequest request)
{
59
userid = null;
60
email = null;
61
}
62
//驗(yàn)證
63
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request)
{
64
ActionErrors errors = new ActionErrors();
65
66
if(this.userid == null || this.userid.length()<1)
{
67
errors.add("userid", new ActionError("userid.required"));
68
}
69
70
if(this.email == null || this.email.length() < 1)
{
71
errors.add("email", new ActionError("email.required"));
72
}
73
74
return errors;
75
}
76
}

2

3

4

5

6

7

8

9

10


11

12

13

14

15



16

17

18

19

20

21


22

23

24



25

26

27


28

29

30



31

32

33


34

35

36



37

38

39


40

41

42



43

44

45


46

47

48



49

50

51


52

53

54



55

56

57

58



59

60

61

62

63



64

65

66



67

68

69

70



71

72

73

74

75

76

從代碼我們可以看出,SignForm除了實(shí)現(xiàn)bean的getter和setter功能外還實(shí)現(xiàn)了簡單的驗(yàn)證,即驗(yàn)證userid和email是否為空,若空則出錯(cuò)!
關(guān)于form的action,我們在講action和編輯struts-config.xml文件時(shí)會(huì)進(jìn)行說明。
Struts學(xué)習(xí)心得之Struts流程篇(3) -示例 續(xù)
第二步:實(shí)現(xiàn)controller。在Struts中繼承自Action。調(diào)用Model,實(shí)現(xiàn)數(shù)據(jù)的深層次檢驗(yàn)(email是否存在)和數(shù)據(jù)的插入,程序的跳轉(zhuǎn)等。代碼如下:
SignAction.java
說明:
1、SignAction實(shí)現(xiàn)MVC中的controller,通過mapping參數(shù)來實(shí)現(xiàn)跳轉(zhuǎn),在controller中調(diào)用了Model中的一些操作,根據(jù)操作結(jié)果來實(shí)現(xiàn)跳轉(zhuǎn)。
2、程序中包括了Struts的錯(cuò)誤處理(請見本blog的《struts錯(cuò)誤處理》)、資源文件的使用,并且好多處代碼都和struts的配置文件struts-config.xml有聯(lián)系
3、關(guān)鍵代碼處都有詳細(xì)的注釋,若還有疑問,請您留言,我們共同探討。
第三步:實(shí)現(xiàn)Model,業(yè)務(wù)邏輯。用戶注冊程序比較簡單,主要實(shí)現(xiàn)findUserByUserid()、findUserByEmail()、sendPassword()、saveNewUser()等功能。代碼如下:
SignForm.java
說明:
1、saveNewUser()使用了Hibernate作為持久化工具,關(guān)于Hibernate請參閱相關(guān)資料,也可以留言我們共同討論。
2、sendPassword()使用JavaMail發(fā)送Email,本文件通過SendMail工具類實(shí)現(xiàn)。
3、密碼生成由RandStringGenerator()工具類生成。
4、工具類可以點(diǎn)擊這里下載。
第四步:配置struts-config.xml。
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
<global-forwards> 全局轉(zhuǎn)發(fā)
<!-- 對(duì)應(yīng)SignAction.java 中的return mapping.findForward("home"); -->
<forward name="home" path="/index.jsp"/>
<forward name="userhome" path="/user/userhome.jsp"/>
</global-forwards>

<form-beans>
<!-- bean的聲明,這個(gè)在下面的Action設(shè)置中要用到 -->
<form-bean name="signForm" type="user.SignForm" />
</form-beans>
<!-- 設(shè)置Aciton -->
<action-mappings>
<action path="/sign" 對(duì)應(yīng)<form action>中action的值,在signin.jsp中的action=/login.do
name="signForm" 設(shè)置的formBean,名稱對(duì)應(yīng)<from-bean>中的聲明,在SignAction.java中對(duì)應(yīng)輸入?yún)?shù)ActionForm
type="user.SignAction" Action的類
validate="true" 是否驗(yàn)證
scope="request" 作用域 這些應(yīng)該不用解釋了
input="/user/signin.jsp"> 當(dāng)發(fā)生錯(cuò)誤時(shí)定向的頁面,對(duì)應(yīng)SignAction.java中的mapping.getInputForward()
</action>
</action-mappings>
<!-- ========== 資源文件定義,詳細(xì)信息在《Struts中資源文件使用》中說明=========== -->

<message-resources parameter="Application"/>
</struts-config>
第五步:調(diào)試程序。經(jīng)過上面的說明和代碼示例是不是對(duì)Struts中的MVC架構(gòu)有了比較清晰的了解,我們知道在java特別是j2ee的軟件中,需要設(shè)置很多的配置文件,剛開始的時(shí)候非常煩,特別是頻頻出錯(cuò)的時(shí)候,那種感覺學(xué)java的人應(yīng)該都嘗過哦!但是當(dāng)你徹底了解了配置文件的確切含義,并且能和代碼中的內(nèi)容進(jìn)行聯(lián)系時(shí),就會(huì)豁然開朗了,就不會(huì)覺得象走進(jìn)死胡同似的。
有了上面struts-config.xml中的說明,相信你已經(jīng)和代碼聯(lián)系起來了,如果將這個(gè)程序調(diào)試成功,那么你就可以說我已經(jīng)對(duì)struts設(shè)計(jì)MVC Web程序入門了,一旦跨進(jìn)了這個(gè)門檻,你會(huì)覺得學(xué)習(xí)起來是那么的輕松,一些來得是那么自然。
好了,希望以上三篇文章能帶你走進(jìn)Struts,理解Struts,特別是熟悉Struts的基本流程,當(dāng)然要想對(duì)一種模式由深入的了解,必須要多加實(shí)踐,從實(shí)踐中來體驗(yàn)到它的好處。
最后,希望你能徹底了解Struts,能為你所用。如果有什么意見和評(píng)論,請留言,我們共同討論,共同進(jìn)步。
謝謝你的閱讀!
SignAction.java
1
/**//**
2
* @author han
3
* soochow university
4
* 實(shí)現(xiàn)Action,controller
5
*/
6
public class SignAction extends Action
{
7
8
public ActionForward execute(ActionMapping mapping, ActionForm form,
9
HttpServletRequest request,HttpServletResponse response
10
) throws Exception
{
11
12
/**//* 參數(shù)說明:
13
* ActionMapping 實(shí)現(xiàn)跳轉(zhuǎn),控制頁面
14
* ActionForm 在viewer中實(shí)現(xiàn)的bean,繼承自ActionForm,獲得form中的數(shù)據(jù)
15
* HttpServletRequest request
16
* HttpServeletRsponse response
17
*/
18
19
ActionErrors errors = new ActionErrors(); //錯(cuò)誤處理,詳細(xì)信息見本blog的《Struts錯(cuò)誤處理》
20
21
/**//*
22
* 得到form中的數(shù)據(jù),因?yàn)閒orm中的數(shù)據(jù)在SignForm中,做一類型轉(zhuǎn)換即可;
23
* 這個(gè)要在struts-config.xml中進(jìn)行說明
24
*/
25
SignForm sf = (SignForm) form;
26
27
/**//*
28
* 調(diào)用Model業(yè)務(wù)邏輯。
29
*/
30
SignModel sign = new SignModel();
31
32
sign.setEmail(sf.getEmail());
33
sign.setUserid(sf.getUserid());
34
35
/**//*
36
* 調(diào)用Model的findUserByEmail 和 findUserByUserid 判斷
37
* email和userid是否存在。
38
* 如果存在,則添加出錯(cuò)信息,頁面跳轉(zhuǎn)到mapping.getInputforward(),需要在
39
* struts-config.xml中定義。
40
* 關(guān)于錯(cuò)誤的詳細(xì)信息請參看本blog的《struts錯(cuò)誤處理》文章。
41
*/
42
//email existed
43
if (sign.findUserByEmail())
{
44
errors.add("email.existed",new ActionError("email.existed", sign.getEmail()));
45
this.saveErrors(request, errors);
46
return mapping.getInputForward();
47
}
48
49
//userid existed
50
if (sign.findUserByUserid())
{
51
errors.add("userid.existed", new ActionError("userid.existed",sf.getUserid()));
52
this.saveErrors(request, errors);
53
return mapping.getInputForward();
54
}
55
56
/**//*
57
* 調(diào)用Model的sendPassword將系統(tǒng)生成的密碼發(fā)送到用戶信箱。
58
* 如果發(fā)生錯(cuò)誤轉(zhuǎn)到mapping.getInputForward(),這個(gè)需要在struts-config.xml中定義
59
* 詳細(xì)信息見后面的struts-config.xml文件說明
60
*/
61
if (sign.sendPassword())
{
62
sign.saveNewUser();
63
}else
{ //郵件發(fā)送錯(cuò)誤
64
errors.add("email.send.error", new ActionError("email.send.error", sf.getEmail()));
65
this.saveErrors(request, errors);
66
return mapping.getInputForward();
67
}
68
69
/**//*
70
* 如果注冊成功,頁面跳轉(zhuǎn)到mapping.findForward("home")
71
* 這個(gè)需要在struts-config.xml中定義
72
* 詳細(xì)信息見后面的struts-config.xml文件說明
73
*/
74
return mapping.findForward("home");
75
76
77
}
78
}


2

3

4

5

6



7

8

9

10



11

12


13

14

15

16

17

18

19

20

21


22

23

24

25

26

27


28

29

30

31

32

33

34

35


36

37

38

39

40

41

42

43



44

45

46

47

48

49

50



51

52

53

54

55

56


57

58

59

60

61



62

63



64

65

66

67

68

69


70

71

72

73

74

75

76

77

78

說明:
1、SignAction實(shí)現(xiàn)MVC中的controller,通過mapping參數(shù)來實(shí)現(xiàn)跳轉(zhuǎn),在controller中調(diào)用了Model中的一些操作,根據(jù)操作結(jié)果來實(shí)現(xiàn)跳轉(zhuǎn)。
2、程序中包括了Struts的錯(cuò)誤處理(請見本blog的《struts錯(cuò)誤處理》)、資源文件的使用,并且好多處代碼都和struts的配置文件struts-config.xml有聯(lián)系
3、關(guān)鍵代碼處都有詳細(xì)的注釋,若還有疑問,請您留言,我們共同探討。
第三步:實(shí)現(xiàn)Model,業(yè)務(wù)邏輯。用戶注冊程序比較簡單,主要實(shí)現(xiàn)findUserByUserid()、findUserByEmail()、sendPassword()、saveNewUser()等功能。代碼如下:
SignForm.java
1
/**//**
2
* @author han
3
* soochow university
4
* 用戶注冊的Model
5
*/
6
public class SignModel
{
7
private String email;
8
private String userid;
9
private String MsgBox = "";
10
private String password;
11
private boolean sended;
12
13
14
/**//**
15
* @return Returns the email.
16
*/
17
public String getEmail()
{
18
return email;
19
}
20
/**//**
21
* @param email The email to set.
22
*/
23
public void setEmail(String email)
{
24
this.email = email;
25
}
26
/**//**
27
* @return Returns the userid.
28
*/
29
public String getUserid()
{
30
return userid;
31
}
32
/**//**
33
* @param userid The userid to set.
34
*/
35
public void setUserid(String userid)
{
36
this.userid = userid;
37
}
38
39
//用戶名和email是否存在
40
public boolean findUserByUserid() throws Exception
{
41
String selectsql = "select userid from password where userid = ?";
42
Mysql mysql = new Mysql(selectsql);
43
try
{
44
mysql.setString(1, this.userid);
45
ResultSet rs = mysql.executeQuery();
46
if(!rs.next()) return false;
47
} catch (Exception e)
{
48
throw new Exception("user.select" + e.getMessage());
49
} finally
{
50
mysql.close();
51
}
52
return true;
53
54
}
55
public boolean findUserByEmail() throws Exception
{
56
String selectsql = "select * from password where email = ?";
57
Mysql mysql = new Mysql(selectsql);
58
try
{
59
mysql.setString(1, this.email);
60
ResultSet rs = mysql.executeQuery();
61
if(!rs.next()) return false;
62
} catch (Exception e)
{
63
throw new Exception("user.select" + e.getMessage());
64
} finally
{
65
mysql.close();
66
}
67
return true;
68
}
69
70
public void saveNewUser() throws HibernateException
{
71
Session session = HibernateUtil.currentSession();
72
73
Transaction transaction;
74
try
{
75
transaction = session.beginTransaction();
76
SignForm newUser = new SignForm();
77
newUser.setEmail(this.email);
78
newUser.setUserid(this.userid);
79
80
newUser.setPassword(password);
81
session.save(newUser);
82
transaction.commit();
83
}catch(Exception e)
{
84
//throw new Exception(e);
85
e.printStackTrace();
86
}finally
{
87
HibernateUtil.closeSession();
88
}
89
}
90
91
//發(fā)送email給用戶初始密碼
92
public boolean sendPassword() throws Exception
{
93
94
SendMail sendMail = new SendMail();
95
96
sendMail.setFrom(Constants.FROM);
97
sendMail.setTo(this.email);
98
sendMail.setSubject(Constants.SUBJECT);
99
sendMail.setSmtpHost(Constants.smtpHost);
100
101
// 生成密碼
102
password = new RandStringGenerator(8).generatorString();
103
MsgBox = Constants.WELCOME_MESSAGE_HEAD + "\r用戶名:"+this.userid+"\r密碼:" + this.password + "\r" + Constants.WELCOME_MESSAGE_FOOT;
104
sendMail.setMsgText(MsgBox);
105
106
107
108
try
{
109
sendMail.sendnow();
110
sended = true;
111
}catch (Exception e)
{
112
System.err.println("send mail error:" + e.getMessage());
113
//throw new Exception("send mail error" + e.getMessage());
114
sended = false;
115
}
116
return sended;
117
}
118
}


2

3

4

5

6



7

8

9

10

11

12

13

14


15

16

17



18

19

20


21

22

23



24

25

26


27

28

29



30

31

32


33

34

35



36

37

38

39

40



41

42

43



44

45

46

47



48

49



50

51

52

53

54

55



56

57

58



59

60

61

62



63

64



65

66

67

68

69

70



71

72

73

74



75

76

77

78

79

80

81

82

83



84

85

86



87

88

89

90

91

92



93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108



109

110

111



112

113

114

115

116

117

118

說明:
1、saveNewUser()使用了Hibernate作為持久化工具,關(guān)于Hibernate請參閱相關(guān)資料,也可以留言我們共同討論。
2、sendPassword()使用JavaMail發(fā)送Email,本文件通過SendMail工具類實(shí)現(xiàn)。
3、密碼生成由RandStringGenerator()工具類生成。
4、工具類可以點(diǎn)擊這里下載。
第四步:配置struts-config.xml。



<!-- 對(duì)應(yīng)SignAction.java 中的return mapping.findForward("home"); -->






<form-bean name="signForm" type="user.SignForm" />







name="signForm" 設(shè)置的formBean,名稱對(duì)應(yīng)<from-bean>中的聲明,在SignAction.java中對(duì)應(yīng)輸入?yún)?shù)ActionForm
type="user.SignAction" Action的類

scope="request" 作用域 這些應(yīng)該不用解釋了
input="/user/signin.jsp"> 當(dāng)發(fā)生錯(cuò)誤時(shí)定向的頁面,對(duì)應(yīng)SignAction.java中的mapping.getInputForward()









第五步:調(diào)試程序。經(jīng)過上面的說明和代碼示例是不是對(duì)Struts中的MVC架構(gòu)有了比較清晰的了解,我們知道在java特別是j2ee的軟件中,需要設(shè)置很多的配置文件,剛開始的時(shí)候非常煩,特別是頻頻出錯(cuò)的時(shí)候,那種感覺學(xué)java的人應(yīng)該都嘗過哦!但是當(dāng)你徹底了解了配置文件的確切含義,并且能和代碼中的內(nèi)容進(jìn)行聯(lián)系時(shí),就會(huì)豁然開朗了,就不會(huì)覺得象走進(jìn)死胡同似的。
有了上面struts-config.xml中的說明,相信你已經(jīng)和代碼聯(lián)系起來了,如果將這個(gè)程序調(diào)試成功,那么你就可以說我已經(jīng)對(duì)struts設(shè)計(jì)MVC Web程序入門了,一旦跨進(jìn)了這個(gè)門檻,你會(huì)覺得學(xué)習(xí)起來是那么的輕松,一些來得是那么自然。
好了,希望以上三篇文章能帶你走進(jìn)Struts,理解Struts,特別是熟悉Struts的基本流程,當(dāng)然要想對(duì)一種模式由深入的了解,必須要多加實(shí)踐,從實(shí)踐中來體驗(yàn)到它的好處。
最后,希望你能徹底了解Struts,能為你所用。如果有什么意見和評(píng)論,請留言,我們共同討論,共同進(jìn)步。
謝謝你的閱讀!