web開發的背景知識(了解)
(1)主機/終端
特點:主機負責所有的業務運算和數據的管理,終端只提供操作界面。
優點:可靠
缺點:昂貴,維護困難
(1)二層的c/s:
特點:使用數據庫當服務器(數據庫不僅要保存數據,還需要編寫大量的業務處理邏輯,客戶端
負責界面及部分的業務處理邏輯)。
優點:開發方便
缺點:可移值性差(比如,要換數據庫,就需要重新寫一次業務處理邏輯,因為數據庫的編程語
言是不一樣的)。
另外,要求客戶端跟數據庫之間保持一個數據庫連接,所以,不適合開發大型的應用(數
據庫能夠提供的數據庫連接的個數是有限制的)。
(2)三層的c/s: 客戶端/服務器端程序
特點:數據庫只負責管理數據,所有的業務邏輯寫在應用服務器里面,客戶端負責界面。
優點:可移植性好,適合開發大型應用
缺點:客戶端需要單獨安裝,開發相對比較復雜(需要開發通訊處理模塊,需要自定義協議)。
(3) b/s:
特點: 數據庫只負責管理數據,所有的業務邏輯寫在web服務器里面,客戶端使用標准的瀏覽器。
其實,b/s架構從本質上講,是一種標准化的c/s:即使用標准化的通訊協議(http協議),標
准化的客戶端程序(瀏覽器),標准化的服務器(比如tomcat)。
優點:客戶端不再需要安裝,另外,開發相對簡化(通訊模塊不再需要開發了,也不再需要自定
義協議)。
2、什么是Servlet?
sun公司制訂的一種用於擴展web服務器功能的組件規范。
(1)擴展web服務器功能:
1)早期的web服務器(比如,apache ws,iis)只能夠處理靜態資源(即需要事先將html文件寫好)的
請求,不能夠處理動態資源(需要依據用戶的請求進行計算然后生成對應的html)的請求。
2)早期,可以使用cgi程序來擴展web服務器: cgi程序可以使用很多語言來開發,比如perl,c
等等都可以,但是,cgi程序有幾個問題(比如,開發復雜,可移植差,性能不是特別好,因
為會啟動過多的cgi進程)。
3)servlet也可以擴展web服務器(即動態生成頁面)功能:
方案一:瀏覽器發請求給web服務器(比如,apache ws,iis,這些web服務器本身是不能夠處理靜
態資源的請求的),web服務器判斷是否需要計算,如果需要,會調用servlet容器,servlet
容器再去調用servlet處理請求。
方案二 瀏覽器直接發請求給servlet容器(比如tomcat,jetty),因為servlet容器除了可以運行
servlet之外,同時,也可以充當簡單的web服務器。
(2)組件規范
1)組件:
符合一定規范,實現部分功能的,並且可以部署在相應的容器里面運行的程序模塊。
servlet就是一個組件,我們在寫servlet時,不需要考慮網絡編程相關的問題,這些問題都由servlet
容器(比如:tomcat)去解決。
2)容器:
符合一定規范,為組件提供運行環境和相應的基礎服務(比如網絡服務)的程序。並且管理組件
的生命周期程序。
servlet容器(比如,tomcat或者jboss)會提供servlet的運行環境。
3、如何開發一個servlet?
step1、寫一個java類(servlet只能夠使用java語言來開發),該類需要實現Servlet接口或者繼承
HttpServlet抽象類。
step2、編譯
step3、打包
appname(應用名)
WEB-INF
classes(.class文件)
lib(可選, .jar文件)
web.xml(部署描述文件)
step4、部署
將step3創建的整個文件夾拷貝到servlet容器特定的文件夾(webapps)下面。或者也可以
將整個文件夾先使用jar命令壓縮成.war文件然后再拷貝。
step5、訪問
啟動servlet容器(web服務器),在瀏覽器地址欄輸入http://ip:port/appname/servlet-url其中,
servlet-url參見web.xml。
4、tomcat的安裝和簡單的使用
windows環境:
step1、將tomcat解壓到D:/ 路徑:D:\apache-tomcat-5.5.23
step2、配置環境變量
(1)JAVA_HOME(JDK的主目錄) 必須配置
(2)tomcat的主目錄 可以不配置
(3)tomcat的bin目錄 可以不配置
1)“我的電腦”右擊“屬性”,打開“系統屬性”的“高級”選項卡,找到“環境變量”
2)新建系統變量,或用戶變量
變量名為:JAVA_HOME 變量值為:JDK目錄
step3、啟動 tomcat服務器
進入啟動tomcat的bin目錄下,雙擊“startup.bat”(windows系統)
關閉tomcat服務器
雙擊stutdown.sh
linux環境:
step1、找到tomcat的壓縮文件(比如/opt/apache-tomcat5.5.23.tar.gz),然后解壓到/home/soft01。
(也可以去www.apache.org去下載tomcat)
step2、配置環境變量(大家現在可以不用配置)
cd /home/soft01
vi .bash_profile
在該文件當中,添加
JAVA_HOME: JDK的安裝路徑,比如/opt/java6.0
CATALINA_HOME: tomat的安裝路徑,比如 /home/soft01/apache-tomcat5.5.23
PATH: /home/soft01/apache-tomcat5.5.23/bin
step3、啟動tomcat
cd /home/soft01/apache-tomcat5.5.23/bin
sh startup.sh (或者 sh catalina.sh run)
接下來,打開瀏覽器,輸入:http://localhost:8080
step4,關閉tomcat
cd /home/soft01/apache-tomcat5.5.23/bin
sh shutdown.sh
tomcat的幾個主要文件夾的作用
1)bin: 是一些可執行文件(比如,啟動和關閉tomcat)
2)common: 放置可以被部署到該服務器上面的所有的程序都可以訪問的jar文件。
3)conf:服務器的配置文件。
4)webapps:tomcat的部署文件夾。
5、Servlet是如何運行的?
比如,從瀏覽器地址欄輸入http://ip:port/firstweb/sayHello
(1) 瀏覽器依據ip,port建立與servlet容器之間的連接。
(2) 瀏覽器將請求資源路徑("/firstweb/sayHello") 及相關的參數打包(按照http協議)發送給容器。
(3) 容器拆包,解析請求數據包,將解析之后的結果數據存放到一個request對象里面,同時還會
創建一個response對象。
(4) 容器依據請求資源路徑找到Servlet的配置,然后創建對應的Servlet對象(這兒,會創建
HelloServlet對象)。
(5) 容器調用Servlet對象的service方法(會將step3創建好的request,response對象作為參數傳遞進
來),可以在該方法里面,通過訪問request對象的相應方法來獲取參數值,也可以將處理結果寫
到response對象里。正因為有這樣兩個對象,Servlet不用考慮網絡相關的問題(比如獲取請求
參數,就不用拆包,同樣,將結果輸出給瀏覽器,也不需要打包)。
(6) servlet容器從response對象里面取出處理結果,然后打包,發送給瀏覽器。
(7) 瀏覽器拆包,解析響應數據包,取出數據,生成相應的界面。
6、使用eclipse開發Servlet程序
HelloServlet.java
public class HelloServlet extends HttpServlet{
/* 覆蓋(override)HttpServlet的service方法。
* 服務器在創建好servlet對象之后,會調用該方法來處理請求。
*/
public void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException,IOException{
System.out.println("service方法正在執行...");
//1 讀取請求參數 String name = request.getParameter("name");
//2 處理請求 String rs = "<h1>" + "hello " + name + "</h1>";
//3 生成響應
1)生成一個消息頭content-type,告訴 瀏覽器,返回的數據類型。
response.setContentType("text/html;charset=utf-8");
2)獲得一個輸出流
PrintWriter out = response.getWriter();
3)向流中輸出數據,其實質是,將處理結果存放 到response對象上。
out.println(rs);
4)關閉流*
out.close(); }
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>helloServlet</servlet-name>
<!--servlet-class:一定要將類的完整的名稱寫出來 -->
<servlet-class>web.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/sayHello</url-pattern>
</servlet-mapping>
</web-app>
7、常見錯誤及及解決方式
(1)404
a,錯誤的原因:請求資源路徑寫錯。
b,解決方式:檢查請求資源路徑。 http://ip:port/appname/servlet-url
(2)500
a,錯誤的原因:系統出錯(程序出錯或者是程序所運行的環境,比如數據庫、網絡等出現問題)。
b,解決方式: 檢查代碼(包括配置文件),檢查運行環境。
(3)405
a,錯誤的原因: 找不到service方法
b,解決方式:檢查方法的簽名
8、http協議(了解)
(1)什么是http協議(超文本傳輸控制協議)?
由w3c定義的一種應用層協議,用來定義瀏覽器與web服務器之間通訊的過程及數據的格式。
1)、瀏覽器與服務器之間通訊的過程:
step1、瀏覽器建立與服務器之間的連接
step2、瀏覽器打包(按照http協議的要求),發送請求
step3、服務器處理完請求,將數據打包,發送響應
step4、服務器關閉連接
特點: 一次請求,一次連接。
優點:效率非常高,服務器可以盡可能的為更多的客戶端(瀏覽器)服務。
2)、數據的格式
a、請求數據包
請求行
請求方式 請求資源路徑協議的類型和版本
若干消息頭
消息頭是一些鍵值對,通信的雙方都可以發送。比如,瀏覽器可以發送user-agent消息頭告
訴服務器瀏覽器的類型和版本。
一般來說,一般由瀏覽器或者服務器自動生成,表示特定的含義。有些時候,需要編程生
成一些消息頭。
實體內容
如果發送get請求,實體內容為空。
只有發送post請求時,實體內容才會有數據(即請求參數值,比如nam=tom),如果是get請
求,請求參數會添加到請求資源路徑的后面。
b、響應數據包
狀態行
協議的類型和版本 狀態碼 狀態描述
狀態碼是一個3位數字,由w3c定義的,表示服務器處理請求的一種狀態,比如:
404:依據請求資源路徑,找不到對應的資源
500:系統出錯
200:正常
若干消息頭
比如,服務器可以向瀏覽器發送一個content-type的消息頭,告訴瀏覽器返回的數據類型以
及編碼格式。瀏覽器按照消息頭的內容打開返回的數據。
response.setContentType(“text/html”); 返回的是一個html頁面,編碼格式是ISO-8859-1
response.setContentType(“text/html;charset=utf8”);返回的是一個html頁面,編碼格式是utf-8
實體內容
程序處理的結果
9、get請求與post請求
(1)哪一些情況下,瀏覽器發送get請求
a、直接在瀏覽器地址欄輸入某個地址
b、點擊鏈接
c、表單默認提交
(2)哪一些情況下,瀏覽器發送post請求
a、表單設置了method="post"。
(3)get請求的特點
a、會將請求參數添加到請求資源路徑的后面,因為請求行最多只能存放大約2K左右的數據,所
以適合提交少量的數據給服務器。優點就是提交小數據時方便
b、請求參數會顯示在瀏覽器地址欄,不安全(比如,路由器會記錄這個地址)。
(4)post請求的特點
a、會將請求參數添加到實體內容里面,能夠提供大量的數據給服務器。
b、請求參數不會顯示在瀏覽器地址欄,相對安全。
要注意的是post方式並不會對請求參數加密(這里不安全)。
比如:姓名、密碼需要加密的,需要使用HTTPS協議。 (需要服務器端進行配置)
HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議要比http協議安全。
10、web編程中的編碼問題
1)常識:
a、java語言會將所有字符以unicode編碼格式保存在內存里面。
b、編碼:將以unicode編碼格式對應的字節數組轉換成某種本地編碼格式(gbk,gb2312,utf-8)對應
的字節數組。
c、解碼:將某種本地編碼格式對應的字節數組轉換成unicode編碼格式對應的字節數組。
//encode方法先進行編碼,然后將得到字節數組轉換成一個字符串。
String str = URLEncoder.encode("過兒","utf-8"); 以utf-8格式編碼
System.out.println(str);
String str2 = URLDecoder.decode(str,"utf-8"); 以utf-8格式解碼
System.out.println(str2);
2)servlet如何輸出中文?
(1)產生亂碼問題的原因?
a、out.println(中文):(編碼)
默認采用iso-8859-1編碼格式進行編碼,iso-8859-1,這個編碼是不支持中文的。
b、服務器默認情況下,會發送一個content-type消息頭,該消息頭指定的編碼是iso-8859-1,
瀏覽器會使用該編碼格式打開頁面。(解碼)
(2)解決方式
response.setContentType("text/html;charset=支持中文的某種編碼");
該方法有兩個作用:
作用1:編碼
out.println時,使用正確的編碼格式進行編碼(unicode -- >utf-8)。
作用2:解碼
生成一個消息頭content-type,該消息頭會指定一個編碼,讓瀏覽器以該編碼來打開頁面。
11、表單處理
(1)如何獲得表單的參數值?
a、String request.getParameter(String paraName);
注意:
1)如果paraName與實際傳遞的參數名稱不一致,會返回null。
2)在文本輸入框中,如果不輸入,會獲得空字符串"",需要注意對""的處理。
b、String[] request.getParameterValues(String paraName);
注意:如果有多個請求參數名稱相同,使用個方法。
比如: city=bj&city=wh&city=hz,應該request.getParameterValues("city");
或者
<form action="/web01/first" method="post">
interst:cooking<input type="checkbox" value="cooking" name="interst"/>
finshing<input type="checkbox" value="fishing" name="interst"/>
<input type="submit" value="提交"/>
</form>
服務器端:采用 request.getParameterValues("interstate");獲得用戶的選擇
(2)表單中如果有中文參數,如何處理?
a、亂碼問題產生的原因
瀏覽器會對表單中的中文參數按照打開該表單時編碼格式來編碼
比如,瀏覽器按照utf-8打開頁面,則使用utf-8對該表單的中文參數進行編碼。服務器端,
默認使用iso-8859-1去解碼。
b、解決方式:
step1 在html文件當中,
使用<meta http-equiv="content-type"content="text/html;charset=支持中文的編碼">,讓瀏
覽器以規定的編碼打開頁面
表單要采用post提交方式。
step2 服務器端使用指定的編碼格式去解碼。request.setCharacterEncoding(指定的編碼);
注意:只對post請求有效
12、中文參數傳遞亂碼問題?
自從Tomcat5.x開始,GET和POST方法提交的信息,Tomcat采用了不同的方式來處理編碼
1)對於POST請求,Tomcat會仍然使用request.setCharacterEncoding方法所設置的編碼來處理,如果
未設置,則使用默認的iso-8859-1編碼。
2)而GET請求則不同,Tomcat對GET請求並不會考慮使用request.setCharacterEncoding方法設置的編
碼,而會永遠使用iso-8859-1編碼,因此,tomcat將會使用iso-8859-1將提交的字節轉換成字符串。
方法一:(只適合post請求)
1)<meta http-equiv="content-type"content="text/html;charset=支持中文的編碼">
2)request.setCharacterEncoding(支持中文的編碼)
方法二:(get/post都適用)
new String(str.getBytes(“iso-8859-1”),”支持中文的編碼”);
方法三:(get/post都適用)
1)在傳參數之前先把參數進行轉碼
java.net.URLEncoder.encode(param);
<a href="ds.jsp?url=
<%=java.net.URLEncoder.encode("編碼的是這里","GB2312")%>"
點擊這里
</a>
2)取值時再轉回中文
java.net.URLDecoder.decode(param);
方法四:(只有get適用)
在你的Tomcat目錄-->conf目錄-->server.xml里找出這段:
<Connector port="8080" maxThreads="150" minSpareThreads="25"
maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
debug="0" connectionTimeout="20000"
disableUploadTimeout="true"
<!--在里邊加上這個參數-->
URIEncoding="utf-8"
/>
通知tomcat對於get請求中的參數不再使用iso-8859-1解碼,而是使用utf-8進行
注意url地址后如果有參數並且參數是中文,就只能用二三四方法
13、重定向
1)什么是重定向?
服務器向瀏覽器發送一個狀態碼302及一個location消息頭(值是一個地址,稱之為重定向地址),
瀏覽器收到后,會立即向 location所指向的地址發送請求。
2)如何重定向
response.sendRedirect(String url); 其中,url是重定向的地址。
3)編程要注意的問題
a、重定向之前,不能夠有out.close()或者out.flush()操作。(否則會報錯)
有out.close或者out.flus時,請求經處理后要把處理結果打包響應給瀏覽器。
而response.sendRect也是對瀏覽器請求的響應,這樣就造成了一次請求兩次響應,不符合規范.
b、重定向之前,如果response對象緩存有數據,則這些數據會被清空。
重定向后,只發送一個重定向地址,不會發送實體內容。所以response對象會清空。
response對象里裝的是返回給瀏覽器的實體內容。
4)重定向的特點
重定向的地址是任意的
重定向之后,瀏覽器地址欄的地址變成了location所指定的地址
14、將中文數據插入到數據庫
將數據插入數據庫的過程是編碼:內存中的編碼是unicode。
插入數據庫的過程數據從unicode編碼再變成數據庫的編碼進行入庫。
從數據庫中取出數據是解碼。
step1 要保證數據庫正確地設置了字符集,即字符集必須支持中文
step2 要保證jdbc驅動程序正確地進行了編碼和解碼。
jdbc:mysql://localhost:3306/jd1206db?useUnicode=true&characterEncoding=utf8
告訴jdbc驅動程序當前數據庫的字符集。
因為某些版本的驅動程序不能夠正確地獲知數據庫的字符集設置。
15、DAO
DAO,封裝了數據訪問邏輯,調用者不需要了解底層的數據訪問細節就可以實現數據訪問。
這樣一來,當底層的數據訪問細節發生改變,不會影響到調用者。
如何寫一個DAO?
(1)實體類:為了方便處理數據庫中的記錄,可以定義與記錄對應的實體類,即可以將數據庫中的
某條記錄轉換成一個實體類的實例。
比如Employee類,提供id,name,salary,age屬性及相關的get/set方法,我們可以將t_emp
表中的記錄轉化成一個Employee對象。
(2)DAO接口:
在DAO接口當中,聲明對某個表的所有操作相關的方法。
基本原則: 接口中聲明的方法不要涉及任何具體的實現。
比如:EmployeeDAO接口,
聲明了: public void save(Employee e) throws SQLException;
這種方式不好,因為出現了jdbc的異常類,這就要求實現該方法只能使用jdbc。
換一種方式來聲明,更好
public void save(Employee e) throws Exception;
public List<Employee> findAll() throws Exception;
(3)DAO實現類
采用具體的技術實現DAO接口
比如:使用jdbc實現EmployeeDAO接口,寫一個類EmployeeDAOIdbcImpl。
(4)DAO工廠(工廠模式)
什么是設計模式:是為了解決一類相似的問題提出的解決方案。
工廠設計模式:工廠將對象的創建過程對外屏蔽,為調用者提供符合接口要求的對象(產品)。
比如:Connection conn = DriverManager.get...
16、處理請求資源路徑
比如輸入: http://ip:port/appname/abc.html
servlet處理請求資源路徑的步驟:
step1、依據/appname查找該應用對應的文件夾(比如查找webapps下面的文件夾是否與其匹配)
step2、在找到的文件夾下面,找到web.xml文件,然后使用<url-pattern>與/abc.html匹配。
匹配規則:
精確匹配:即要求<url-pattern>與/abc.html完全一致
通配符匹配:使用“*”代表任意的字符串
比如在<url-pattern>中使用/*表示任意字符串,/abc/*表示有abc的字符串
后綴匹配:不能使用“/”開頭,要求“*.任意的字符串”。
比如:*.do要求以.do為結尾 *.action要求以.action
step3、如果都不匹配,嘗試查找/abc.html靜態頁面,如果找到,則返回該文件,找不到,則返回
404狀態
17、Servlet處理多種請求
一個servlet如何處理多種請求?
step1、使用后綴匹配模式。<url-pattern>*.do</url-pattern>
step2、在service()方法里加入代碼:
獲得請求資源路徑:String url=request.getRequestURI();
分析請求資源路徑,來決定做何種處理
//幾種地址的比較 request的方法
ServletPath:/image.jsp
RequestURI:/elec_qin/image.jsp
ContextPath:/elec_qin
RequestURL:http://localhost:8080/elec_qin/image.jsp
18、servlet生命周期相關核心接口與類
Servlet的框架是由兩個Java包組成的:javax.servlet與javax.servlet.http。
在javax.servlet包中定義了所有的Servlet類都必須實現或者擴展的通用接口和類。
在javax.servlet.http包中定義了采用Http協議通信的HttpServlet類。
Servlet的框架的核心是javax.servlet.Servlet接口,所有的Servlet都必須實現這個接口。
(1)Servlet接口
在Servlet接口中定義了5個方法,
void init(ServletConfig config): 初始化
void service(ServletRequest req,ServletResponse res):
void destory():
ServletConfig getServletCnifg();
String getServletInfo();
Servlet接口依賴於ServletRequest,ServletResponse,ServletConfig接口
(2)ServletConfig接口
用來訪問初始化參數。
當容器讀取web.xml配置文件中<servlet>配置節信息,根據<servlet-class>配置節信息創建servlet
對象,同時根據<init-param>配置節信息創建ServletConfig對象。然后調用init方法,把創建好的
ServletConfig對象傳給servlet對象。注意是servlet容器實現了ServletConfig接口。
ServletConfig對象封裝了初始化參數。定義了如下的方法:
public abstract String getServletName();
public abstract ServletContext getServletContext();
public abstract String getInitParameter(String s);
public abstract Enumeration getInitParameterNames();
(2)GenericServlet抽象類
GenericServlet實現了Servlet和ServletConfig接口。擁有了兩個接口的所有方法。
實現servlet接口中的部分方法,主要是實現了init,destroy方法。
GenericServlet類的主要結構
1)有一個屬性:private ServletConfig config;
2)getServletCnifg()方法,獲得容器創建好的Servletconfig對象
public ServletConfig getServletConfig(){
return this.config;
}
容器調用init方法時,將容器創建好的ServletConfig對象賦值給屬性config。
再通過調用getServletConfig方法得到ServletConfig對象。
3)init方法()的實現
public void init(ServletConfig config)throw ServletException{
this.config=config;//把對象的引用通過屬性保存下來
this.init();
}
//鈎子方法,存在的意義就是被覆蓋。當servlet要求有復雜的初始化步驟時,覆蓋此方法
public void init()throws ServletException(){
//什么都沒有做
}
4)service方法沒有實現,由子類實現
public abstract void service(ServletRequest servletrequest, ServletResponse servletresponse)
5)實現類destroy方法
public void destroy(){ }
6)也實現了ServletConfig接口的getServletName,getServletContext,getInitParameter,
getInitParameterNames。
實現原理是在這些方法中調用了容器創建好的ServletConfig(屬性config)中相應的方法
(3)HttpServlet抽象類
繼承了GenericServlet,主要實現了service方法
定義doGet(),doPost(),doHead(),doPut(),doDelete(),doOptions()方法。
根據請求方式來調用相應的doXXX方法。
實現了GenericServlet的service方法。
service方法的主要邏輯是根據請求來調用相應的doXXX方法。
(4)ServletRequest與ServletResponse接口
(5)HttpServletRequest與HttpServletResponse接口
HttpServletRequest接口繼承ServletRequest接口
HttpServletResponse接口繼承ServletResponse接口
這些接口由servlet容器實現,在請求到達時創建request對象和response對象傳入到service方法中。
(6)整個過程
1、Web客戶向Servlet容器(Tomcat)發出Http請求
2、Servlet容器分析客戶的請求信息
3、Servlet容器創建一個HttpRequest對象,將客戶請求的信息封裝到這個對象中
4、Servlet容器創建一個HttpResponse對象
5、Servlet容器調用HttpServlet對象的service方法,
把HttpRequest對象與HttpResponse對象作為參數傳給 HttpServlet對象
6、HttpServlet調用HttpRequest對象的有關方法,獲取Http請求信息
7、HttpServlet調用HttpResponse對象的有關方法,生成響應數據
8、Servlet容器把HttpServlet的響應結果傳給Web客戶
19、servlet的生命周期
所謂生命周期,指的是servlet容器如何創建servlet對象、如何初始化、如何調用servlet對象的方法來
處理請求以及如何銷毀servlet對象的整個過程。
(1)實例化(就是創建servlet對象,調用構造器)
a、什么是實例化?
容器調用servlet的構造器,創建一個servlet對象。(new一個對象)
b、什么時候實例化?
1)當請求到達容器時,容器查找該servlet對象是否存在,如果不存在,才會創建實例。
2)容器在啟動時,或者新部署了某個應用時,會檢查web.xml當中,servlet是否有
load-on-starup配置。如果有,則會創建該servlet實例。
load-on-starup參數要求是一個>=0的整數,值越小,優先級越高(先被實例化)。
注意:servlet容器在默認情況下,對於每個servlet,只會創建一個實例。(單例模式)
(2)初始化
a、什么是初始化?
servlet容器在創建好servlet對象之后,會立即調用該對象的init方法。
b、GenericServlet已經提供了init方法,一般情況下,我們不再需要寫init方法了。
GenericServlet提供的init方法是這樣實現的:
將容器提供的ServletConfig對象保存下來,並且提供了getServletConfig方法用來獲得ServletConfig對象。
c、servlet的初始化參數
1)使用<init-param>來配置初始化參數
<init-param>
<param-name>company</param-name>
<param-value>北京</param-value
</init-param>
2)調用ServletConfig對象的getInitParameter方法獲得參數值
d、如何實現自己的初始化方法?
建議override init()方法
e、init方法只會執行一次
(3)就緒/調用
a、什么是就緒?
servlet容器在收到請求之后,會調用servlet對象的service方法來處理請求。
b、HttpServlet的service方法是如何實現的?
依據請求方式(get/post)分別調用doGet/doPost方法。
可以覆蓋HttpServlet提供的doGet/doPost方法,也可以直接覆蓋HttpServlet提供的service方法
(4)銷毀
a、什么是銷毀?
servlet容器依據自身的算法,在不再需要servlet對象時,會調用該對象的destroy方法,
然后,再刪除該對象。
Servlet容器停止或者重新啟動:Servlet容器調用Servlet對象的destroy方法來釋放資源。
b、GenericServlet已經實現了destroy方法。釋放資源
c,、該方法只會執行一次。
在servlet的整個生命周期當中,init,destroy只會執行一次,而service方法會執行多次。
20、案例
(1)產品計價
發送請求:http://localhost:8088/web04_2/pricing.html
pricing.html
<body style="font-size:30px;font-style:italic;">
<form action="pricing" method="post">
<fieldset>
<legend>產品計價</legend>
原始價格:<input name="basePrice"/><br/>
出售城市:<select name="city" style="width:150px;">
<option value="bj">北京</option>
<option value="sh">上海</option>
<option value="cs">長沙</option>
</select><br/>
<input type="submit" value="確定"/>
</fieldset>
</form>
</body>
點擊按鈕發送請求:http://localhost:8088/web04_2/pricing
配置文件web.xml
<servlet>
<servlet-name>pricingServlet</servlet-name>
<servlet-class>web.PricingServlet</servlet-class>
<init-param>
<param-name>taxRate</param-name>
<param-value>bj,0.08;sh,0.09;cs,0.03</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>pricingServlet</servlet-name>
<url-pattern>/pricing</url-pattern>
</servlet-mapping>
類PricingServlet.java
public class PricingServlet extends HttpServlet{
private HashMap<String,Double> taxRates =
new HashMap<String,Double>();
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
double basePrice = Double.parseDouble(request.getParameter("basePrice"));
String city = request.getParameter("city");
double taxRate = taxRates.get(city);
double price = basePrice * ( 1 + taxRate);
out.println("實際售價:" + price);
}
public void init() throws ServletException {
System.out.println("init...初始化,從配置文件中讀取各個城市的利率");
ServletConfig config = getServletConfig();
//bj,0.08;sh,0.09;cs,0.03
String taxRate = config.getInitParameter("taxRate");
String[] strs = taxRate.split(";");
for(int i=0;i<strs.length;i++){
String str = strs[i]; //bj,0.08
String[] str1 = str.split(",");
taxRates.put(str1[0], Double.parseDouble(str1[1]));
}
}
(2)servlet生命周期
<servlet>
<servlet-name>some</servlet-name>
<servlet-class>web.SomeServlet</servlet-class>
<!-- 初始化參數 -->
<init-param>
<param-name>company</param-name>
<param-value>工商銀行</param-value>
</init-param>
<init-param>
<param-name>address</param-name>
<param-value>北京上地</param-value>
</init-param>
<!-- 啟動就加載 參數值越小,優先級越高 -->
<load-on-startup>1</load-on-startup>
</servlet>
public class SomeServlet extends HttpServlet{
public SomeServlet(){
System.out.println("SomeServlet's constructor...");
}
public void init() throws ServletException {
System.out.println("SomeServlet's init...");
}
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException{
System.out.println("SomeServlet's doGet...");���ServletConfig����
ServletConfig config = getServletConfig();
String company = config.getInitParameter("company");
System.out.println("company:" + company);
}
public void destroy() {
System.out.println("SomeServlet's destroy...");
}