參考資料
前言
本人菜鳥犬绒,入IT只為當鼓勵師。本編文章對 Servlet 作簡要介紹兑凿,其中包括講解:Servlet是什么凯力、Servlet的功能、Servlet的生命周期礼华、HttpServlet對象咐鹤。
一、Servlet是什么
- 一門用于開發(fā)動態(tài)web資源的技術圣絮,由sun公司提供祈惶。
- java類編寫的服務端應用程序
- Servlet程序是由web服務器(tomcat等)調用的
說簡單點,就是Sun公司開發(fā)出了一套API(java.servlet
扮匠、java.sevlet.http
等)捧请,你可以用這些api開發(fā)Java程序,用來處理客戶端請求棒搜,并控制輸出的響應(向客戶端瀏覽器輸出的內容)疹蛉。
總結起來,你只需要:
① 編寫一個實現(xiàn)了servlet接口的java類力麸;
② 把開發(fā)好的Java類部署到web服務器中可款。
所以,有時我們也稱實現(xiàn)了servlet接口的java程序為Servlet克蚂。
二闺鲸、Servlet的功能
- 對客戶端發(fā)送的數(shù)據(jù)進行讀取和攔截
客戶端發(fā)送一個請求會攜帶數(shù)據(jù)(url中的參數(shù),頁面表單提交埃叭,ajax請求)摸恍,當一個Servlet接收到請求,java Servlet中的類可以通過提供的方法獲得這些參數(shù)(request.getParameterName(name)
等)赤屋。因此Servlet可以起攔截作用立镶,在請求前先判斷該客戶端能否做出這些請求 壁袄,若能再從服務器得到請求的資源。
圖例
讀取客戶端的請求的隱含數(shù)據(jù)
客戶端請求的數(shù)據(jù)可分為:隱含數(shù)據(jù)谜慌,顯式數(shù)據(jù)。
隱含數(shù)據(jù):不存在于URL中莺奔,而存在于請求的來源欣范,緩存數(shù)據(jù)(cookie)、客戶端類型(在header中)令哟。
顯式數(shù)據(jù):用戶可見的恼琼,表單數(shù)據(jù)(來自于form)或URL參數(shù)。
Servlet都可處理屏富。-
運行結果或者生成結果
一個Web應用程序對客戶端發(fā)出的請求做出響應時晴竞,一般有很多中間過程才能得到結果,Servlet就擔起了這個中間角色功能狠半。(后面深入學習會知道噩死,javaweb開發(fā)中的控制層是由Servlet實現(xiàn)的,就是常說的MVC中的C)
圖例 發(fā)送響應的數(shù)據(jù)
Servlet對客戶端做出響應并經(jīng)過處理得出結果后神年,會對客戶端發(fā)送響應的數(shù)據(jù)已维,讓客戶端獲取請求的結果數(shù)據(jù)。
三已日、Servlet的生命周期
Servlet的生命周期包含3個階段:
1. 初始化階段
當web服務器收到客戶端對某一url地址的訪問請求時垛耳,若該url配置了對應的Servlet程序,則開始該階段飘千。
- web服務器檢查是否已經(jīng)裝載并創(chuàng)建了該Servlet的實例對象堂鲜。如果是,則跳過初始化階段护奈,否則進入下一步缔莲。
- 裝載(由Servlet容器裝載一個Servlet類,把它裝在到Java內存中)并創(chuàng)建該Servlet的一個實例對象霉旗,與
web.xml
中的配置對應起來酌予。 - 調用Servlet實例對象的
init()
方法。在整個Servlet生命周期中奖慌,init()
方法只被調用一次抛虫。
步驟圖示
首次訪問的兩個注意點
2. 運行階段
該階段實際響應客戶端的請求。
- Servlet創(chuàng)建
HttpServletRequest
和HttpServletResponse
對象简僧,前者與HTTP協(xié)議有關建椰,后者與協(xié)議無關。 - 調用
service(HttpServletRequest request, HttpServletResponse response)
方法岛马,該方法通過request對象獲得請求對象的信息并加以處理棉姐,再由response對象給客戶端做出響應屠列。
3. 消亡階段
- web應用程序被停止或重新啟動之前乃坤,Servlet容器將調用
destroy()
方法苛让,對Servlet對象進行銷毀,釋放其所占資源湿诊。在整個Servlet生命周期中狱杰,destory()
方法只被調用一次。
四厅须、創(chuàng)建Servlet的步驟
- 引入相應的包仿畸,如:
java.servlet
或java.servlet.http
包,兩個包的區(qū)別是前者與協(xié)議無關朗和,后者與HTTP協(xié)議相關错沽。 - 創(chuàng)建一個擴展類,如本例中的 HelloServlet眶拉,并繼承
HttpServlet
類甥捺。(一般的,HttpServlet
類封裝了很多基于HTTP協(xié)議下的Servlet功能镀层,基本夠用镰禾,若自己想開發(fā)一個協(xié)議可繼承GenericServlet
類) - override
doGet()
或doPost()
方法,doGet()
響應get請求唱逢,doPost()
響應Post請求吴侦。或者可以overrideservice()
方法坞古,對所有請求統(tǒng)一處理备韧。欲詳細了解service()
,doGet()
痪枫,doPost()
等方法织堂,請看:五、關于 Servlet奶陈、HttpServlet易阳、GenericServlet。
代碼示例:
package com.javaweb.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/* 用注入聲明的方式表示這是一個 Servlet 類吃粒,不用在web.xml中配置 Servlet */
@WebServlet (
urlPatterns = { "/HelloServlet" },
name = " helloServlet "
)
// 繼承HttpServlet類
public class HelloServlet extends HttpServlet {
// 序列化潦俺,可以自動生成或者自行定義
private static final long serialVersionUID = 1L;
// 一、初始化階段的 init() 方法
public void init() throws ServletException {
System.out.println("初始化 init 方法");
}
// 過程二執(zhí)行的方法有一定的順序與條件,詳細請看: 五事示、關于 Servlet早像、HttpServlet、GenericServlet
// 二肖爵、調用 public service 方法
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
System.out.println("調用 public service 方法");
// 設定頁面的MINE類型和字符集
response.setContentType("text/html;charset=utf-8");
// 輸出響應
PrintWriter out = response.getWriter();
out.println("收到 service 請求");
}
// 二卢鹦、調用 protected service 方法
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException {
System.out.println("調用 protected service 方法");
}
// 二、調用 doGet() 方法
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
// 二劝堪、調用 doPost() 方法
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("調用 doPost() 方法");
// 設定頁面的MINE類型和字符集
response.setContentType("text/html;charset=utf-8");
// 輸出響應
PrintWriter out = response.getWriter();
out.println("收到 HelloServlet doPost() 請求");
}
// 三冀自、消亡階段的 destory() 方法
public void destory() {
System.out.println("調用 destory() 方法");
}
}
五、關于 Servlet幅聘、HttpServlet凡纳、GenericServlet
Servlet
來自于 javax.servlet.Servlet
HttpServlet
來自于 javax.servlet.http.HttpServlet
GenericServlet
來自于 javax.servlet.GenericServlet
1. Servlet
servlet 是一個接口窃植,如果實現(xiàn)這個接口帝蒿,那么就必須實現(xiàn)接口里面定義的所有方法。一般開發(fā)不會去自己實現(xiàn)該接口巷怜,它只提供了一種規(guī)范葛超,供 開發(fā)者 自己來編寫相關的實現(xiàn)
-
可以看出,Servlet接口提供了5個必須實現(xiàn)的方法
Servlet 接口中的方法
2. GenericServlet
-
GenericServlet
定義了一個通用的延塑,無關協(xié)議的Servlet绣张。如果要在Web應用中使用Http進行Servlet通信,請擴展HttpServlet
(即繼承HttpServlet
) -
在《JSP從零開始》的第100—101頁有GenericServlet類的部分源代碼关带,讀者有興趣可研究一下
api中對 GenericServlet 抽象類的說明 - 下面是
GenericServlet
中的方法
GenericServlet 類中的方法
3. HttpServlet
HttpServlet
是一個抽象類侥涵,它繼承了 GenericServlet
抽象類,而 GenericServlet
類實現(xiàn)了 Servlet
接口宋雏,所以HttpServlet
類也就默認實現(xiàn)了 Servlet
接口芜飘。默認實現(xiàn)規(guī)范而實用,開發(fā)web端的servlet程序磨总,一般我們只需繼承 HttpServlet
類就可以了
創(chuàng)建
HttpServlet
的步驟:
①繼承HttpServlet
抽象類嗦明;
②覆蓋HttpServlet
的部分方法,如覆蓋doGet()
或doPost()
方法蚪燕;
③獲取HTTP請求信息娶牌。通過HttpServletRequest
對象來檢索HTML表單所提交的數(shù)據(jù)或URL上的查詢字符串;
④生成HTTP響應結果馆纳。通過HttpServletResponse
對象生成響應結果诗良,它有個getWriter()
方法,該方法返回一個PrintWriter
對象鲁驶。-
它總共有10個方法累榜,其中實現(xiàn)了:
HttpServlet 中的方法
① 2個重載的 service() 方法
- 在servlet中默認情況下,無論是get還是post 提交過來 都會經(jīng)過
service()
方法來處理,然后轉向到doGet()
或doPost()
方法壹罚,所以默認情況(沒有重寫service方法)下葛作,service()
是用來轉向的。 - 如果你在自己的servlet類中覆蓋了
service()
方法猖凛,那么service()
就不是用來轉向了赂蠢,而是用來處理業(yè)務,這時不論客戶端是用post還是get來請求此servlet辨泳,都會執(zhí)行service()
方法也只能執(zhí)行servlet()
方法虱岂,不會去執(zhí)行doPost()
或doGet()
方法。
各個方法的執(zhí)行順序和條件
② doGet()菠红,doPost()第岖,doOptions(),doTrace()试溯,doDelete()蔑滓,doHead()投放, doPut() 這7個方法
- 最常用的還是
doGet()
和doPost()
谜酒,但一般來說我們是用不到doGet()
方法的堵第。doGet()
方法提交表單時會在url后邊顯示提交內容辆苔,并不安全蛤肌。而且doGet()
方法只能提交256個字符(1024字節(jié))懈玻,而doPost()
沒有限制泽示,因為get方式數(shù)據(jù)的傳輸載體是URL(提交方式能form钳幅,也可以是任意的URL鏈接)付鹿,而POST是HTTP頭鍵值對(只能以form方式提交)澜汤。通常我們使用的都是doPost()
方法,你只要在servlet中讓這兩個方法互相調用就行了舵匾。
③ getLastModified(HttpServletRequest req) 方法
- 傳入?yún)?shù)為一個
HttpServletRequest
對象 - 返回一個數(shù)值俊抵,該值為從 1970年1月1日 到 該
HttpServletRequest
對象最近一次修改的那個時刻 走過的毫秒數(shù)。
最后纽匙,分享我用PowerDesigner創(chuàng)建的面向對象模型的關系圖來說明三者的關聯(lián):
- 對PowerDesigner有興趣的讀者可以看該文集中的:PowerDesigner入門篇务蝠,可初步了解一下這個軟件的使用。