題外話:
自從由開發(fā)人員轉(zhuǎn)為培訓(xùn)講師后,發(fā)現(xiàn)了很多技術(shù)的知識(shí)點(diǎn)是不全面的,在開發(fā)中只要只要能夠滿足功能就OK了。但是發(fā)現(xiàn)到了講師的職位后還需要掌握很多以前很多沒有接觸過的知識(shí)點(diǎn)。然而對(duì)于開發(fā)經(jīng)驗(yàn)少,代碼量不多,基礎(chǔ)有限的學(xué)員來說就很頭大了。所以我想將知識(shí)點(diǎn)進(jìn)行整理,寫成一系列的文章,能夠讓他們快速的上手和開發(fā),這也是為什么將這一系列文章起名叫做《SSH快速開發(fā)與整合》。本系列文章的書寫目的不是讓大家了解多么新的技術(shù)和多么炫的頁(yè)面效果,而是想為入門者提供一條更快的捷徑。
由于平時(shí)白天工作比較忙時(shí)間緊,一直擔(dān)心怕寫不完,但這次我下了很大決心將他寫完。由于是第一次寫這么系統(tǒng)的文章,里面會(huì)有很多不足,就請(qǐng)大家擔(dān)待吧。
開發(fā)環(huán)境:在本系列文章中,我們會(huì)用到的開發(fā)工具是 MyEclipse6.5 Blue 版本,服務(wù)為:Tomcat6.0,數(shù)據(jù)庫(kù)為:Mysql6.0 。
第1章基礎(chǔ)知識(shí)回顧
為了能夠更清晰的了解struts 框架工作原理,我們需要對(duì) JSP 部分知識(shí)點(diǎn)進(jìn)行回顧。
1.1 web應(yīng)用程序中的Model1和Model2模型
在最早的 Java Web 應(yīng)用程序中,JSP文件幾乎擔(dān)任了所有的工作如圖1-1所示。其中包括了頁(yè)面的顯示、請(qǐng)求跳轉(zhuǎn)的控制、業(yè)務(wù)的處理等等,這種方式在實(shí)際的項(xiàng)目開發(fā)中項(xiàng)目要是代碼量少點(diǎn)也就無所謂了,如果代碼量大的情況下要用這種方式開發(fā)出來的程序html代碼、java代碼、javascript腳本代碼混在一起對(duì)于后期代碼的維護(hù)是一件非常麻煩的事。所以這種方式的開發(fā)沒有被業(yè)界給出什么明確的定義。

為了解決這種問題Sun公司制定了兩種架構(gòu)模式 Model 1 和 Model 2。
1.1.1 Model 1

為了解決直接在JSP頁(yè)面上寫代碼可讀性差的問題,我們將原先寫在JSP頁(yè)面上的業(yè)務(wù)邏輯代碼提出來寫到JavaBean中如圖1-2。此時(shí)JSP充當(dāng)了視圖層為客戶端提供了請(qǐng)求和響應(yīng),再由Jsp調(diào)用JavaBean進(jìn)行處理業(yè)務(wù)邏輯。這種架構(gòu)方式我們往往稱之為 Model 1。
在Model1中,我們可以看出 Jsp 不但完成了對(duì)客戶端的請(qǐng)求和應(yīng)答工作還擔(dān)任著調(diào)用不同業(yè)務(wù)類的請(qǐng)求跳轉(zhuǎn)工作。但這個(gè)架構(gòu)比起直接在JSP頁(yè)面上寫代碼已經(jīng)好多了,Model1中已經(jīng)將業(yè)務(wù)代碼從頁(yè)面中的控制代碼和Html代碼中進(jìn)行了分離。至少當(dāng)程序業(yè)務(wù)代碼出現(xiàn)問題時(shí),我們不再會(huì)到JSP頁(yè)面中去尋找修改業(yè)務(wù)邏輯代碼了。
此時(shí)Model1比起直接在JSP頁(yè)面上寫代碼已經(jīng)強(qiáng)多了,但是對(duì)于大型項(xiàng)目而言還是不能夠滿足,畢竟JSP頁(yè)面中還有控制跳轉(zhuǎn)的代碼存在。
1.1.2 Model 2

為了解決Mdel1中控制器代碼和HTML、JavaScript代碼寫在一起,Sun公司制定了Model2,在Model2中引入了“控制器”概念,而控制器往往由Servlet充當(dāng)。此時(shí)JSP頁(yè)面中只剩下了HTML代碼和一些客戶端javascript腳本代碼,請(qǐng)求由控制器Servlet進(jìn)行控制跳轉(zhuǎn)到不同的JAVABean或者JSP頁(yè)面,這樣Jsp中只提供對(duì)客戶的界面視圖我們用英文單詞View表示,而Servlet只完成請(qǐng)求的跳轉(zhuǎn)工作我們可以用英文Controller表示,JavaBean中完成業(yè)務(wù)邏輯和數(shù)據(jù)的封裝我們可以用Model表示,這樣我們將 View - Controller - Model三個(gè)單詞的第一個(gè)字母提取出來就是我們所謂的 MVC 模式了。
1.2 MVC的概述
MVC是Model(模型) - View視圖()-Controller(控制器)三個(gè)單詞的縮寫。MVC是J2EE中的一種模式,是針對(duì)于整個(gè)應(yīng)用程序結(jié)構(gòu)而言的,所以MVC模式從尺度上來講要比我們平時(shí)所說的java設(shè)計(jì)模式要大。關(guān)于java設(shè)計(jì)模式在此就不做過多的講解了,讀者可以參考閻宏博士所寫的《Java與模式》 。
在J2EE中有很多技術(shù)都可以實(shí)現(xiàn)MVC模式比如我們馬上要學(xué)習(xí)的struts框架技術(shù)就是MVC的一種實(shí)現(xiàn),還有 JSF、WebWork等等。
接下來我們需要搞清楚的一個(gè)問題就是J2EE、MVC、Struts他們之間樣的關(guān)系。在此我們拿 宇宙 、太陽(yáng)系 、地球來進(jìn)行說明,我們都知道我們的地球是隸屬于太陽(yáng)系的,但是這個(gè)太陽(yáng)系中不僅僅只有地球,還有火星、木星等等星球構(gòu)成。例子中的太陽(yáng)系就相當(dāng)于MVC模式而地球相當(dāng)于struts,從而我們知道MVC模式并不是只有struts能夠?qū)崿F(xiàn),還有其他很多技術(shù)可以實(shí)現(xiàn),像上面提到過的JSF、WebWork等等技術(shù),所以我們只能夠說struts是MVC模式的一種實(shí)現(xiàn)方式。而MVC和J2EE之間的關(guān)系就像太陽(yáng)系和宇宙的關(guān)系一樣,宇宙中有很多類似于太陽(yáng)系的星系,所以MVC知識(shí)J2EE中的一種模式,如圖1-4所示:

1.3 配置一個(gè) Servlet
為了讓讀者對(duì)程序有更深的理解,在程序?qū)嵗腥慷疾扇∈止ご罱ê团渲谩?/span>(此處作者使用的是MyEclipse6.5Bule版本)
首先我們?cè)?/span>MyEclipse中創(chuàng)建一個(gè)web應(yīng)用程序步驟如下:
(1) 選擇 “File 菜單 → New → Project ”,如圖1-5所示。

(2)在彈出的New Project窗口中,選擇“Web Project”,然后點(diǎn)擊“Next”按鈕,如圖1-6所示。


圖1-6 圖1-7
(3)在“New Web Project”對(duì)話框的“Project Name:”為web工程起個(gè)名字,此處我們起名為 frist_Servlet 。將J2EE Specification Level選中 Java EE5.0 其他的不需要改變,默認(rèn)就好了,單擊“Finish”按鈕,如圖 1-7 所示。
(4)對(duì)準(zhǔn)創(chuàng)建好的web工程下的“src目錄右鍵” → 選擇“New” → 選擇“Class”,如圖1-8所示。

(5)在彈出的New Java Class對(duì)話框中的 “Name:”中輸入HelloWord,其他的不需改變,點(diǎn)擊“Finish”按鈕,如圖1-9所示。

(6)修改HelloWorld類的代碼,讓其繼承于javax.servlet.http.HttpServlet類,代碼如下:
2
3 import javax.servlet.http.HttpServlet;
4
5 public class HelloWorld extends HttpServlet{
6
7 }
8
注意:在web應(yīng)用程序中要想使一個(gè)普通的Class類變成一個(gè)Serlvet 就必須讓這個(gè)普通類繼承與javax.servlet.http.HttpServlet類。
(7)讓HelloWorld重寫父類javax.servlet.http.HttpServlet中的“doGet” 方法,并輸出“HelloWorld”,具體代碼如下:
2 import javax.servlet.http.HttpServlet;
3 import javax.servlet.http.HttpServletRequest;
4 import javax.servlet.http.HttpServletResponse;
5
6 public class HelloWorld extends HttpServlet {
7 @Override
8 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
9 throws ServletException, IOException {
10 System.out.println("HelloWorld");
11 }
12 }
13
(8)打開“WebRoot”目錄 → “WEB-INF” → “web.xml”文件,如圖所示。在打開的“web.xml”文件中配置 HelloWorld 。
2 <web-app version="2.5"
3 xmlns="http://java.sun.com/xml/ns/javaee"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
6 http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
7 <servlet>
8 <servlet-name>helloWorld</servlet-name>
9 <servlet-class> com.study.struts.HelloWorld</servlet-class>
10 </servlet>
11 <servlet-mapping>
12 <servlet-name>helloWorld</servlet-name>
13 <url-pattern>*.do</url-pattern>
14 </servlet-mapping>
15 <welcome-file-list>
16 <welcome-file>index.jsp</welcome-file>
17 </welcome-file-list>
18 </web-app>
19
(9)打開“WebRoot”目錄中的“index.jsp”文件,并修改代碼如下:
2 <html>
3 <head>
4 <title>手工配置的第一個(gè)Servlet</title>
5 </head>
6 <body>
7 <a href="click.do">點(diǎn)擊測(cè)試Servlet程序</a>
8 </body>
9 </html>
10
注意:在“index.jsp”頁(yè)面第一句代碼中:
<%@ page language="java" pageEncoding="GB18030"%>
有一個(gè)pageEncoding 屬性,他表示當(dāng)前jsp頁(yè)面的編碼格式,GB18030為編碼集,pageEncoding 屬性默認(rèn)為ISO-8859-1編碼集,而ISO-8859-1編碼中是不支持中文字符的,換句話說也就是如果當(dāng)前頁(yè)面pageEncoding="ISO-8859-1" 那么當(dāng)前頁(yè)面中是不允許出現(xiàn)中文字符的,所以此處我們將pageEncoding的值改為“GB18030”。在Java編程中常見的編碼集有以下幾種:
編碼集名稱 |
是否支持中文 |
ISO-8859-1 |
不支持 |
UTF-8 |
支持 |
GB2312 |
支持 |
GBK |
支持 |
GB18030 |
支持 |
(10)部署應(yīng)用程序,如圖1-11所示。

(11)運(yùn)行web程序,如圖1-12所示,在 IE 瀏覽器地址欄輸入http://localhost:8080/frist_Servlet 如圖1-13所示。


由于我們?cè)?/span>9步中寫過 <a href="click.do">點(diǎn)擊測(cè)試Servlet程序</a> 代碼當(dāng)我們點(diǎn)擊超鏈接“點(diǎn)解測(cè)試Servlet程序”時(shí),瀏覽器將會(huì)發(fā)出一個(gè) click.do 的請(qǐng)求,此時(shí)web應(yīng)用程序會(huì)接收到瀏覽器發(fā)出的click.do請(qǐng)求,因?yàn)槲覀冊(cè)诘?/span>8步中為web.xml配置過如下代碼:
2 <servlet-name>helloWorld</servlet-name>
3 <url-pattern>*.do</url-pattern>
4 </servlet-mapping>
5
6
其中 <url-pattern>*.do</url-pattern> 表示只要jsp頁(yè)面發(fā)出的所有以 .do 結(jié)尾的請(qǐng)求都會(huì)被攔截。攔截后的請(qǐng)求會(huì)自動(dòng)找到 <servlet-name>helloWorld</servlet-name> 并取得到值 “helloWorld” ,并會(huì)帶著“helloWorld”值到下面這段代碼去尋找<servlet>的子標(biāo)簽<servlet-name>的值和“helloWorld”相等的一項(xiàng)。
2 <servlet-name>helloWorld</servlet-name>
3 <servlet-class> com.study.struts.HelloWorld</servlet-class>
4 </servlet>
5
當(dāng)請(qǐng)求被尋找到后程序會(huì)自動(dòng)將請(qǐng)求跳轉(zhuǎn)到所對(duì)應(yīng)的<servlet-class>標(biāo)簽所配置的類中執(zhí)行doGet 方法,調(diào)用流程如圖1-14所示。

程序最后會(huì)在Eclipse控制臺(tái)上打印“”,運(yùn)行結(jié)果如圖1-15所示:
