JAVA学习篇--Servlet详解
Servlet由來
?
???? 做過BS項目的人都知道,瀏覽器能夠根據HTML靜態標記語言來顯示各式各樣的網頁。但是如果我們需要在網頁上完成一些業務邏輯:比如登陸驗證。或者說網頁顯示的內容在服務器的數據庫中。如果是這樣,除了負責顯示的HTML標記之外,必須還要有完成這些業務功能的代碼存在。這種網頁我們就叫做動態網頁。
?????對于靜態網頁而言,服務器上存在的是一個個純HTML文件。當客戶端瀏覽器發出HTTP請求時,服務器可以根據請求的URL找到對應的HTML文件,并將HTML代碼返回給客戶端瀏覽器。
? ? ?但是對于動態網頁,服務器上除了找到需要顯示的HTML標記外,還必須執行所需要的業務邏輯,然后將業務邏輯運算后的結果和需要顯示的HTML標記一起生成新的HTML代碼。最后將新的帶有業務邏輯運算結果的HTML代碼返回給客戶端。
?
為了實現動態網頁的目標,JavaServlet技術因應而生,它能夠以一種可移植的方法來提供動態的、面向用戶的內容。
?
簡單來說:
servlet是在服務器上運行的小程序。Servlet的主要功能在于交互式地瀏覽和修改數據,生成動態Web內容,是為web開發服務的。
?
CGI與Servlet對比
?
開始的時候,公共網關接口(CommonGateway Interface,CGI)腳本是生成動態內容的主要技術。雖然使用得非常廣泛,但CGI腳本技術有很多的缺陷,這包括平臺相關性和缺乏可擴展性。為了避免這些局限性,JavaServlet技術因應而生,它能夠以一種可移植的方法來提供動態的、面向用戶的內容。處理用戶請求。
?
?????對比一:當用戶瀏覽器發出一個Http/CGI的請求,或者說調用一個CGI程序的時候,服務器端就要新啟用一個進程(而且是每次都要調用),調用CGI程序越多(特別是訪問量高的時候),就要消耗系統越多的處理時間,只剩下越來越少的系統資源,對于用戶來說,只能是漫長的等待服務器端的返回頁面了,這對于電子商務激烈發展的今天來說,不能不說是一種技術上的遺憾。
而Servlet充分發揮了服務器端的資源并高效的利用。每次調用Servlet時并不是新啟用一個進程,而是在一個Web服務器的進程中共享和分離線程,而線程最大的好處在于可以共享一個數據源,使系統資源被有效利用。故servlet不是線程安全的,單實例多線程的
對比二:傳統的CGI程序,不具備平臺無關性特征,系統環境發生變化,CGI程序就要癱瘓,而Servlet具備Java的平臺無關性,在系統開發過程中保持了系統的可擴展性、高效性。
對比三:傳統技術中,一般大都為二層的系統架構,即Web服務器+數據庫服務器,導致網站訪問量大的時候,無法克服CGI程序與數據庫建立連接時速度慢的瓶頸,從而死機、數據庫死鎖現象頻繁發生。而我們的Servlet有連接池的概念,它可以利用多線程的優點,在系統緩存中事先建立好若干與數據庫的連接,到時候若想和數據庫打交道可以隨時跟系統"要"一個連接即可,反應速度可想而知。
?
?
Servlet的運行過程
?
? ? ?⒈ 客戶端發送請求至服務器端;
? ⒉服務器端根據web.xml文件中的Servlet相關配置信息,將客戶端請求轉發到相應的Servlet
? ? ?⒊ Servlet引擎調用Service()方法,根據request對象中封裝的用戶請求與數據庫進行交互,返回數據之后,Servlet會將返回的數據封裝到response對象中;
? ⒋ Servlet生成響應內容并將其傳給服務器。響應內容動態生成,通常取決于客戶端的請求
⒌ 服務器將響應返回給客戶端
?
Servlet生命周期
? ??
?
1) 加載和實例化;在第一次請求Servlet時,Servlet容器將會創建Servlet實例;
2)?初始化;Servlet容器加載完成Servlet之后,必須進行初始化,此時,init方法將被調用;
3)?Servlet初始化之后,就處于響應請求的就緒狀態,此時如有客戶端請求發送,就會調用Servlet實例的service()方法,并且根據用戶的請求方式,調用doPost或者doGet方法;
4) 最后,Servlet容器負責將Servlet實例進行銷毀,調用destroy方法實現;
對于更多的客戶端請求,Server創建新的請求和響應對象,仍然激活此Servlet的service()方法,將這兩個對象作為參數傳遞給它。如此重復以上的循環,但無需再次調用init()方法。
????一般Servlet只初始化一次(只有一個對象),當Server不再需要Servlet時(一般當Server關閉時),Server調用Servlet的Destroy()方法。
?
實例解析:
? ? ? ? ? ? ?
html代碼--客戶端瀏覽器
[html]?view plaincopy print?
配置文件
[html]?view plaincopy print?
servlet處理過程
[java]?view plaincopy print?
Servlet如何同時處理多個請求?
? ? ? ?Servlet采用多線程來處理多個請求的同時訪問。Servlet容器通過線程池來管理維護服務請求。所謂線程池,相當于數據庫連接池,實際上是等待執行代碼的一組線程,叫做工作者線程。Servlet容器通過一個調度線程來管理工作者線程。
· 當容器收到一個Servlet的訪問請求,調度者線程就從線程池中選出一個工作者線程,將用戶請求傳遞給該線程,然后由該線程處理Servlet的service()方法;
· 當這個線程在執行的時候,容器收到一個新的請求,調度者線程再次從線程池中選出一個新的工作者線程;
· 當容器同時收到對同一個Servlet的多個請求時,那么Servlet的service方法將在多線程中并發執行。
注:
? ? 1.Servlet容器默認采用單實例多線程的方式來處理請求。這樣減少了產生Servlet實例的開銷,提升了對請求的響應時間;
? ? 2.對于Tomcat容器來講,可以在其server.xml中通過<Connector>中設置線程池中的線程數目。
如何開發線程安全的Servlet?
? ? ? ?Servlet容器采用多線程來處理請求,提高性能的同時也造成了線程安全問題。要開發線程安全的Servlet應該從一下幾個方面進行:
1. ?變量的線程安全; 多線程并不共享局部變量,所以我們要盡可能的在Servlet中使用局部變量;
2. ?代碼塊的線程安全; 使用同步塊Synchronized,防止可能調用的代碼塊;但是要注意的是,要盡可能得縮小同步代碼的方范圍,不要在service方法和響應方法上直接使用同步,這會嚴重影響性能。
3. ?屬性的線程安全; ServletContext,HttpSession,ServletRequest對象中屬性;
4. ?使用同步集合; 使用Vector代替ArrayList,使用HashTable代替HashMap;
5. ?不要在Servlet中創建自己的線程來完成某個功能; Servlet本身就是多線程的,如果再創建新的線程,將會導致線程執行復雜化,出現線程安全問題;
6. ?在多個Servlet中,對外部對象,比如:文件;進行修改操作一定要加鎖,做到互斥訪問;
總結:
?
? ? 一個servlet就是Java編程語言中的一個類,它被用來擴展服務器的性能,服務器上駐留著可以通過“請求-響應”編程模型來訪問的應用程序。Servlet通過解析http請求,取得客戶端的參數來進行下一步操作。其實簡單來說,servlet就是一個控制器,取參數,調用業務邏輯.
? ? 而在.net 中HttpHandler是一個HTTP請求的真正處理中心,也正是在這個HttpHandler容器中,ASP.NET?Framework才真正地對客戶端請求的服務器頁面做出編譯和執行,并將處理過后的信息附加在HTTP請求信息流中再次返回到HttpModule中。
from:?http://blog.csdn.net/hejingyuan6/article/details/30273879
總結
以上是生活随笔為你收集整理的JAVA学习篇--Servlet详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ServletJSP学习笔记--导航
- 下一篇: Spring 概述