Servlet詳解

轉(zhuǎn)自其他平臺
https://blog.csdn.net/hejingyuan6/article/details/30273879
Servlet由來
  做過BS項目的人都知道衍锚,瀏覽器能夠根據(jù)HTML靜態(tài)標記語言來顯示各式各樣的網(wǎng)頁。但是如果我們需要在網(wǎng)頁上完成一些業(yè)務邏輯:比如登陸驗證≌庀或者說網(wǎng)頁顯示的內(nèi)容在服務器的數(shù)據(jù)庫中帖世。如果是這樣,除了負責顯示的HTML標記之外,必須還要有完成這些業(yè)務功能的代碼存在靶累。這種網(wǎng)頁我們就叫做動態(tài)網(wǎng)頁侵歇。
  對于靜態(tài)網(wǎng)頁而言骂澄,服務器上存在的是一個個純HTML文件。當客戶端瀏覽器發(fā)出HTTP請求時盒至,服務器可以根據(jù)請求的URL找到對應的HTML文件酗洒,并將HTML代碼返回給客戶端瀏覽器。
  但是對于動態(tài)網(wǎng)頁枷遂,服務器上除了找到需要顯示的HTML標記外樱衷,還必須執(zhí)行所需要的業(yè)務邏輯,然后將業(yè)務邏輯運算后的結(jié)果和需要顯示的HTML標記一起生成新的HTML代碼酒唉。最后將新的帶有業(yè)務邏輯運算結(jié)果的HTML代碼返回給客戶端矩桂。
  為了實現(xiàn)動態(tài)網(wǎng)頁的目標,JavaServlet技術(shù)因應而生痪伦,它能夠以一種可移植的方法來提供動態(tài)的侄榴、面向用戶的內(nèi)容。

簡單來說:
  servlet是在服務器上運行的小程序网沾。Servlet的主要功能在于交互式地瀏覽和修改數(shù)據(jù)癞蚕,生成動態(tài)Web內(nèi)容,是為web開發(fā)服務的辉哥。

CGI與Servlet對比
  開始的時候桦山,公共網(wǎng)關(guān)接口(CommonGateway Interface攒射,CGI)腳本是生成動態(tài)內(nèi)容的主要技術(shù)。雖然使用得非常廣泛恒水,但CGI腳本技術(shù)有很多的缺陷会放,這包括平臺相關(guān)性和缺乏可擴展性。為了避免這些局限性钉凌,JavaServlet技術(shù)因應而生咧最,它能夠以一種可移植的方法來提供動態(tài)的、面向用戶的內(nèi)容御雕。處理用戶請求矢沿。
   對比一:當用戶瀏覽器發(fā)出一個Http/CGI的請求,或者說調(diào)用一個CGI程序的時候酸纲,服務器端就要新啟用一個進程(而且是每次都要調(diào)用)咨察,調(diào)用CGI程序越多(特別是訪問量高的時候),就要消耗系統(tǒng)越多的處理時間福青,只剩下越來越少的系統(tǒng)資源摄狱,對于用戶來說,只能是漫長的等待服務器端的返回頁面了无午,這對于電子商務激烈發(fā)展的今天來說媒役,不能不說是一種技術(shù)上的遺憾。
  而Servlet充分發(fā)揮了服務器端的資源并高效的利用宪迟。每次調(diào)用Servlet時并不是新啟用一個進程酣衷,而是在一個Web服務器的進程中共享和分離線程,而線程最大的好處在于可以共享一個數(shù)據(jù)源次泽,使系統(tǒng)資源被有效利用穿仪。故servlet不是線程安全的,單實例多線程的
  對比二:傳統(tǒng)的CGI程序意荤,不具備平臺無關(guān)性特征啊片,系統(tǒng)環(huán)境發(fā)生變化,CGI程序就要癱瘓玖像,而Servlet具備Java的平臺無關(guān)性紫谷,在系統(tǒng)開發(fā)過程中保持了系統(tǒng)的可擴展性、高效性捐寥。
  對比三:傳統(tǒng)技術(shù)中笤昨,一般大都為二層的系統(tǒng)架構(gòu),即Web服務器+數(shù)據(jù)庫服務器握恳,導致網(wǎng)站訪問量大的時候瞒窒,無法克服CGI程序與數(shù)據(jù)庫建立連接時速度慢的瓶頸,從而死機乡洼、數(shù)據(jù)庫死鎖現(xiàn)象頻繁發(fā)生崇裁。而我們的Servlet有連接池的概念陵像,它可以利用多線程的優(yōu)點,在系統(tǒng)緩存中事先建立好若干與數(shù)據(jù)庫的連接寇壳,到時候若想和數(shù)據(jù)庫打交道可以隨時跟系統(tǒng)"要"一個連接即可,反應速度可想而知妻怎。

Servlet的運行過程

  • ⒈ 客戶端發(fā)送請求至服務器端壳炎;
  • ⒉服務器端根據(jù)web.xml文件中的Servlet相關(guān)配置信息,將客戶端請求轉(zhuǎn)發(fā)到相應的Servlet
  • ⒊ Servlet引擎調(diào)用Service()方法逼侦,根據(jù)request對象中封裝的用戶請求與數(shù)據(jù)庫進行交互匿辩,返回數(shù)據(jù)之后,Servlet會將返回的數(shù)據(jù)封裝到response對象中榛丢;
  • ⒋ Servlet生成響應內(nèi)容并將其傳給服務器铲球。響應內(nèi)容動態(tài)生成,通常取決于客戶端的請求
  • ⒌ 服務器將響應返回給客戶端


    Servlet的運行過程

Servlet生命周期

Servlet生命周期

    1. 加載和實例化晰赞;在第一次請求Servlet時稼病,Servlet容器將會創(chuàng)建Servlet實例;
    1. 初始化掖鱼;Servlet容器加載完成Servlet之后然走,必須進行初始化,此時戏挡,init方法將被調(diào)用芍瑞;
    1. Servlet初始化之后,就處于響應請求的就緒狀態(tài)褐墅,此時如有客戶端請求發(fā)送拆檬,就會調(diào)用Servlet實例的service()方法,并且根據(jù)用戶的請求方式妥凳,調(diào)用doPost或者doGet方法竟贯;
    1. 最后,Servlet容器負責將Servlet實例進行銷毀逝钥,調(diào)用destroy方法實現(xiàn)澄耍;

對于更多的客戶端請求,Server創(chuàng)建新的請求和響應對象晌缘,仍然激活此Servlet的service()方法齐莲,將這兩個對象作為參數(shù)傳遞給它。如此重復以上的循環(huán)磷箕,但無需再次調(diào)用init()方法选酗。
  一般Servlet只初始化一次(只有一個對象),當Server不再需要Servlet時(一般當Server關(guān)閉時),Server調(diào)用Servlet的Destroy()方法岳枷。

實例解析:

實例解析

html代碼--客戶端瀏覽器

<span style="font-family:KaiTi_GB2312;"><html>
    <head>
        <title>學生管理</title>
    </head>
    <body>
        <h1>根據(jù)出生日期段查詢</h1>
        <form action="queryStudentServlet">
            出生日期 :<input type="text" name="beginDate">至<input type="text" name="endDate">
            <input type="submit" value="查詢學生">
        </form>
    </body>
</html>
</span>

配置文件

<span style="font-family:KaiTi_GB2312;"><servlet>
        <servlet-name>StudentMgrServlet</servlet-name>
        <servlet-class>StudentServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>StudentMgrServlet</servlet-name>
        <url-pattern>/queryStudentServlet</url-pattern>
    </servlet-mapping>
</span>

Servlet處理過程

<span style="font-family:KaiTi_GB2312;">    import java.text.*;
    import java.util.*;
    import java.io.*;
    import javax.servlet.http.*;
    import javax.servlet.*;
    
    import com.bjpowernode.exam.model.*;
    import com.bjpowernode.exam.manager.*;
    
    public class StudentServlet extends HttpServlet {
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
            doPost(request, response);
        }
        
        public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
            
            String sBeginDate = request.getParameter("beginDate");
            String sEndDate = request.getParameter("endDate");
            
            Date beginDate = new Date();
            Date endDate = new Date();
            try {
                beginDate = new SimpleDateFormat("yyyy-MM-dd").parse(sBeginDate);
                endDate = new SimpleDateFormat("yyyy-MM-dd").parse(sEndDate);
             }catch(Exception e) {
                e.printStackTrace();         
             }   
            
            
            StudentManager studentManager = new StudentManagerImpl();
            List<Student> studentList = studentManager.findStudentList(beginDate, endDate);
            //表格省略…
        }
    }
</span>

Servlet如何同時處理多個請求芒填?
  Servlet采用多線程來處理多個請求的同時訪問呜叫。Servlet容器通過線程池來管理維護服務請求。所謂線程池殿衰,相當于數(shù)據(jù)庫連接池朱庆,實際上是等待執(zhí)行代碼的一組線程,叫做工作者線程闷祥。Servlet容器通過一個調(diào)度線程來管理工作者線程娱颊。

  • 當容器收到一個Servlet的訪問請求,調(diào)度者線程就從線程池中選出一個工作者線程凯砍,將用戶請求傳遞給該線程箱硕,然后由該線程處理Servlet的service()方法;
  • 當這個線程在執(zhí)行的時候悟衩,容器收到一個新的請求剧罩,調(diào)度者線程再次從線程池中選出一個新的工作者線程;
  • 當容器同時收到對同一個Servlet的多個請求時座泳,那么Servlet的service方法將在多線程中并發(fā)執(zhí)行惠昔。

注:
  1. Servlet容器默認采用單實例多線程的方式來處理請求。這樣減少了產(chǎn)生Servlet實例的開銷挑势,提升了對請求的響應時間舰罚;
  2. 對于Tomcat容器來講,可以在其server.xml中通過<Connector>中設置線程池中的線程數(shù)目薛耻。

如何開發(fā)線程安全的Servlet营罢?
  Servlet容器采用多線程來處理請求,提高性能的同時也造成了線程安全問題饼齿。要開發(fā)線程安全的Servlet應該從一下幾個方面進行:

    1. 變量的線程安全饲漾; 多線程并不共享局部變量,所以我們要盡可能的在Servlet中使用局部變量缕溉;
    1. 代碼塊的線程安全考传; 使用同步塊Synchronized,防止可能調(diào)用的代碼塊证鸥;但是要注意的是僚楞,要盡可能得縮小同步代碼的方范圍,不要在service方法和響應方法上直接使用同步枉层,這會嚴重影響性能泉褐。
    1. 屬性的線程安全; ServletContext鸟蜡,HttpSession膜赃,ServletRequest對象中屬性;
    1. 使用同步集合揉忘; 使用Vector代替ArrayList跳座,使用HashTable代替HashMap端铛;
    1. 不要在Servlet中創(chuàng)建自己的線程來完成某個功能; Servlet本身就是多線程的疲眷,如果再創(chuàng)建新的線程禾蚕,將會導致線程執(zhí)行復雜化,出現(xiàn)線程安全問題狂丝;
    1. 在多個Servlet中换淆,對外部對象,比如:文件美侦;進行修改操作一定要加鎖,做到互斥訪問魂奥;

總結(jié):
  一個servlet就是Java編程語言中的一個類菠剩,它被用來擴展服務器的性能,服務器上駐留著可以通過“請求-響應”編程模型來訪問的應用程序耻煤。Servlet通過解析http請求具壮,取得客戶端的參數(shù)來進行下一步操作。其實簡單來說哈蝇,servlet就是一個控制器棺妓,取參數(shù),調(diào)用業(yè)務邏輯.
   而在.net 中HttpHandler是一個HTTP請求的真正處理中心炮赦,也正是在這個HttpHandler容器中怜跑,ASP.NET Framework才真正地對客戶端請求的服務器頁面做出編譯和執(zhí)行,并將處理過后的信息附加在HTTP請求信息流中再次返回到HttpModule中吠勘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末性芬,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子剧防,更是在濱河造成了極大的恐慌植锉,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峭拘,死亡現(xiàn)場離奇詭異俊庇,居然都是意外死亡,警方通過查閱死者的電腦和手機鸡挠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門辉饱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拣展,你說我怎么就攤上這事鞋囊。” “怎么了瞎惫?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵溜腐,是天一觀的道長译株。 經(jīng)常有香客問我,道長挺益,這世上最難降的妖魔是什么歉糜? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮望众,結(jié)果婚禮上匪补,老公的妹妹穿的比我還像新娘。我一直安慰自己烂翰,他們只是感情好夯缺,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著甘耿,像睡著了一般踊兜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上佳恬,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天捏境,我揣著相機與錄音,去河邊找鬼毁葱。 笑死垫言,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的倾剿。 我是一名探鬼主播筷频,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼前痘!你這毒婦竟也來了截驮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤际度,失蹤者是張志新(化名)和其女友劉穎葵袭,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乖菱,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡坡锡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了窒所。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鹉勒。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吵取,靈堂內(nèi)的尸體忽然破棺而出禽额,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布脯倒,位于F島的核電站实辑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏藻丢。R本人自食惡果不足惜剪撬,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望悠反。 院中可真熱鬧残黑,春花似錦、人聲如沸斋否。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茵臭。三九已至疫诽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間笼恰,已是汗流浹背踊沸。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工歇终, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留社证,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓评凝,卻偏偏與公主長得像追葡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子奕短,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 如果網(wǎng)頁顯示的內(nèi)容在服務器的數(shù)據(jù)庫中宜肉,除了負責顯示的HTML標記之外,必須還要有完成這些業(yè)務功能的代碼存在翎碑。這種網(wǎng)...
    鄭在學_blog閱讀 502評論 0 0
  • 一、概念: servlet servlet是一種運行服務器端的java應用程序莉擒,具有獨立于平臺和協(xié)議的特性酿炸,并且可...
    學編程的小屁孩閱讀 3,159評論 0 1
  • Java Servlets是Java的一項Web技術(shù)。 這是Java的第一個Web技術(shù)涨冀,許多新的Web技術(shù)已經(jīng)到來...
    FantJ閱讀 3,961評論 0 4
  • 這篇文章, 我主要分享JavaWeb動態(tài)網(wǎng)頁開發(fā).要談JavaWeb動態(tài)網(wǎng)頁開發(fā).我們就要來了解Servlet, ...
    sixleaves閱讀 975評論 0 6
  • 聲明:本欄目所使用的素材都是凱哥學堂VIP學員所寫填硕,學員有權(quán)匿名,對文章有最終解釋權(quán)鹿鳖;凱哥學堂旨在促進VIP學員互...
    凱哥學堂閱讀 258評論 0 0