從計算機軟件開發進入網絡時代,就開始涉及到通信問題。在客戶/服務器(也叫C/S應用)時期,每一個軟件都有本身的客戶端和服務器端軟件。而且客戶端和服務器端之間的通信協議差異也很大。後來隨着互聯網的發展,基於瀏覽器/服務器的應用逐漸成爲主流,通信協議也統一到HTTP協議。可是,在HTTP協議之上,如何處理來自客戶端的請求信息,以及如何對請求進行迴應,則經歷了很長時間也沒有統一下來。目前,對於這個問題的解決方案主要有兩種,一個是CGI,另外一個是Servlet。web
CGI(Common Gateway Interface),通用網關接口瀏覽器
通用網關接口,簡稱CGI,是一種根據請求信息動態產生迴應內容的技術。經過CGI,Web 服務器能夠將根據請求不一樣啓動不一樣的外部程序,並將請求內容轉發給該程序,在程序執行結束後,將執行結果做爲迴應返回給客戶端。也就是說,對於每一個請求,都要產生一個新的進程進行處理。由於每一個進程都會佔有不少服務器的資源和時間,這就致使服務器沒法同時處理不少的併發請求。另外CGI程序都是與操做系統平臺相關的,雖然在互聯網爆發的初期,CGI爲開發互聯網應用作出了很大的貢獻,可是隨着技術的發展,開始逐漸衰落。服務器
Servlet網絡
Servlet最初是在1995年由James Gosling提出的,由於使用該技術須要複雜的Web服務器支持,因此當時並無獲得重視,也就放棄了。後來隨着Web應用複雜度的提高,並要求提供更高的併發處理能力,Servlet被從新撿起,並在Java平臺上獲得實現,如今提起Servlet,指的都是Java Servlet。Java Servlet要求必須運行在Web服務器當中,與Web服務器之間屬於分工和互補關係。確切的說,在實際運行的時候Java Servlet與Web服務器會融爲一體,如同一個程序同樣運行在同一個Java虛擬機(JVM)當中。與CGI不一樣的是,Servlet對每一個請求都是單獨啓動一個線程,而不是進程。這種處理方式大幅度地下降了系統裏的進程數量,提升了系統的併發處理能力。另外由於Java Servlet是運行在虛擬機之上的,也就解決了跨平臺問題。若是沒有Servlet的出現,也就沒有互聯網的今天。併發
在Servlet出現以後,隨着使用範圍的擴大,人們發現了它的一個很大的一個弊端。那就是爲了可以輸出HTML格式內容,須要編寫大量重複代碼,形成沒必要要的重複勞動。爲了解決這個問題,基於Servlet技術產生了JavaServet Pages技術,也就是JSP。Servlet和JSP二者分工協做,Servlet側重於解決運算和業務邏輯問題,JSP則側重於解決展現問題。Servlet與JSP一塊兒爲Web應用開發帶來了巨大的貢獻,後來出現的衆多Java Web應用開發框架都是基於這兩種技術的,更確切的說,都是基於Servlet技術的。框架
Java Servlet與Web容器之間的關係ide
Java是一種動態加載和運行的語言。也就是說當應用程序持有一個類的地址(CLASSPATH)和名稱(包名和類名)的狀況下,能夠在程序運行期間任什麼時候候加載這個類,並建立和使用該類的對象。Servlet就是基於這個機制與Web容器融合在一塊兒的。目前已知的全部支持Java Servlet的Web容器都是採用Java開發的。當Web容器接收到來自客戶端的請求信息以後,會根據URL中的Web元件地址信息到Servlet隊列中查找對應的Servlet對象,若是找到則直接使用,若是沒有找到則加載對應的類,並建立對象。也就是說,Servlet對象是在第一次被使用的時候才建立的,而且一旦建立就會被反覆使用,再也不建立新的對象。全部建立出的Servlet對象會在Web服務器中止運行的時候統一進行垃圾回收。操作系統
爲了解決客戶端請求地址與Java Servlet之間對應關係問題,Web容器須要一個用來描述這種對應關係的文件,通常是web.xml文件。若是一個Web應用程序中存在不少個Servlet,那麼web.xml會變得很是龐大。在Servlet 3.0規範推出以後,容許在Servlet代碼中使用聲明式語法來代替web.xml中的描述信息,這才讓web.xml瘦身下來。下圖是這個過程的一個示意圖。線程
在這個圖中,咱們僅僅是概要的,採用以比較容易理解的方式描述了Web容器與Servlet之間的關係,以及當接受到請求以後的處理流程。在實際的Web容器中,會比這要複雜不少。xml