servlet--百度百科

Servlet(Server Applet),全稱 Java Servlet, 未有中文譯文。是用Java編寫的服務器端程序。其主要功能在於交互式地瀏覽和修改數據,生成動態Web內容。狹義的Servlet是指Java語言實現 的一個接口,廣義的Servlet是指任何實現了這個Servlet接口的類,通常狀況下,人們將Servlet理解爲後者。
Servlet運行於支持Java的應用服務器中。從原理上講,Servlet能夠響應任何類型的請求,但絕大多數狀況下Servlet只用來擴展基於HTTP協議的Web服務器。
最先支持Servlet標準的是JavaSoft的Java Web Server。此後,一些其它的基於Java的Web服務器開始支持標準的Servlet。
外文名
Servlet
類    別
程序
環    境
Java  applet
平    臺
Java Web Server

由來

編輯
Servlet 是在 服務器上運行的小程序。這個詞是在 Java applet的環境中創造的,Java applet 是一種看成單獨文件跟網頁一塊兒發送的小程序,它一般用於在客戶端運行,結果獲得爲用戶進行運算或者根據用戶互做用定位圖形等服務。
服務器上須要一些程序,經常是根據用戶輸入訪問數據庫的程序。這些一般是使用 公共網關接口Common Gateway Interface,CGI)應用程序完成的。然而,在服務器上運行 Java,這種程序可以使用 Java 編程語言實現。在通訊量大的服務器上,JavaServlet 的優勢在於它們的執行速度更快於 CGI 程序。各個用戶請求被激活成單個程序中的一個線程,而 無需建立單獨的進程,這意味着 服務器端處理請求的 系統開銷將明顯下降。
實現過程
最先支持 Servlet 技術的是 JavaSoft 的 Java Web Server。此後,一些其它的基於 Java 的 Web Server 開始支持標準的 Servlet API。Servlet 的主要功能在於交互式地瀏覽和修改數據,生成動態 Web 內容。這個過程爲:
1) 客戶端發送請求至服務器端;
2) 服務器將請求信息發送至 Servlet;
3) Servlet 生成響應內容並將其傳給 服務器。響應內容動態生成,一般取決於客戶端的請求;
4) 服務器將響應返回給客戶端。
Servlet 看起來像是一般的 Java 程序。Servlet 導入特定的屬於 Java Servlet API 的包。由於是對象 字節碼,可動態地從網絡加載,能夠說 Servlet 對 Server 就如同 Applet對 Client 同樣,可是,因爲 Servlet 運行於 Server 中,它們並不須要一個 圖形用戶界面。從這個角度講,Servlet 也被稱爲 FacelessObject。
一個 Servlet 就是 Java 編程語言中的一個類,它被用來擴展 服務器的性能,服務器上駐留着能夠經過「請求-響應」編程模型來訪問的應用程序。雖然 Servlet 能夠對任何類型的請求產生響應,但一般只用來擴展 Web 服務器的應用程序。
目前最新版本爲 3.1。

命名

編輯
Servlet 的命名能夠看出 sun 命名的特色,如 Applet 表示小應用程序;Scriptlet = Script + Applet,表示小腳本程序;一樣 Servlet = Service + Applet,表示小服務程序。

生命週期

編輯
  1. 客戶端請求該 Servlet;
  2. 加載 Servlet 類到內存;
  3. 實例化並調用init()方法初始化該 Servlet;
  4. service()(根據請求方法不一樣調用doGet() 或者 doPost(),此外還有doHead()、doPut()、doTrace()、doDelete()、doOptions());
  5. destroy()。
加載和實例化 Servlet。這項操做通常是動態執行的。然而,Server 一般會提供一個管理的選項,用於在 Server 啓動時強制裝載和初始化特定的 Servlet。
Server 建立一個 Servlet的實例
第一個客戶端的請求到達 Server
Server 調用 Servlet 的 init() 方法(可配置爲 Server 建立 Servlet 實例時調用,在 web.xml 中 <servlet> 標籤下配置 <load-on-startup> 標籤,配置的值爲整型,值越小 Servlet 的啓動優先級越高)
一個客戶端的請求到達 Server
Server 建立一個請求對象,處理客戶端請求
Server 建立一個響應對象,響應客戶端請求
Server 激活 Servlet 的 service() 方法,傳遞請求和響應對象做爲參數
service() 方法得到關於請求對象的信息,處理請求,訪問其餘資源,得到須要的信息
service() 方法使用響應對象的方法,將響應傳回Server,最終到達客戶端。service()方法可能激活其它方法以處理請求,如 doGet() 或 doPost() 或程序員本身開發的新的方法。
對於更多的客戶端請求,Server 建立新的請求和響應對象,仍然激活此 Servlet 的 service() 方法,將這兩個對象做爲 參數傳遞給它。如此重複以上的循環,但無需再次調用 init() 方法。通常 Servlet 只初始化一次( 只有一個對象),當 Server 再也不須要 Servlet 時(通常當 Server 關閉時),Server 調用 Servlet 的 destroy() 方法。

工做模式

編輯
客戶端發送請求至 服務器
服務器啓動並調用 Servlet,Servlet 根據客戶端請求生成響應內容並將其傳給服務器
服務器將響應返回客戶端

比較

編輯

與 Applet 的比較

類似之處:
* 它們不是獨立的應用程序,沒有 main() 方法。
* 它們不是由用戶或程序員調用,而是由另一個應用程序(容器)調用。
* 它們都有一個生存週期,包含 init() 和 destroy() 方法。
不一樣之處:
* Applet具備很好的圖形界面( AWT),與瀏覽器一塊兒,在客戶端運行。
* Servlet 則沒有圖形界面,運行在 服務器端。

與 CGI 比較

與傳統的 CGI 和許多其餘相似 CGI 的技術相比,Java Servlet 具備更高的效率,更容易使用,功能更強大,具備更好的可移植性,更節省投資。在將來的技術發展過程當中,Servlet 有可能完全取代 CGI。
在傳統的 CGI中,每一個請求都要啓動一個新的進程,若是 CGI 程序自己的執行時間較短,啓動進程所須要的開銷極可能反而超過實際執行時間。而在 Servlet 中,每一個請求由一個輕量級的 Java 線程處理(而不是重量級的操做系統進程)。
在傳統 CGI 中,若是有 N 個併發的對同一 CGI程序的請求,則該CGI程序的代碼在內存中重複裝載了 N 次;而對於 Servlet,處理請求的是 N 個線程,只須要一份 Servlet 類代碼。在性能優化方面,Servlet 也比 CGI 有着更多的選擇。
* 方便
Servlet 提供了大量的實用工具例程,例如自動地解析和解碼 HTML 表單數據、讀取和設置 HTTP頭、處理 Cookie、跟蹤會話狀態等。
* 功能強大
在Servlet中,許多使用傳統 CGI 程序很難完成的任務均可以輕鬆地完成。例如,Servlet 可以直接和 Web 服務器交互,而普通的 CGI 程序不能。Servlet 還可以在各個程序之間共享數據,使得數據庫 鏈接池之類的功能很容易實現。
* 可移植性好
Servlet 用 Java 編寫,Servlet API具備完善的標準。所以,爲 IPlanet Enterprise Server 寫的 Servlet 無需任何實質上的改動便可移植到 ApacheMicrosoftIIS 或者 WebStar。幾乎全部的主流 服務器都直接或經過 插件支持 Servlet。
* 節省投資
不只有許多廉價甚至免費的 Web 服務器可供我的或小規模網站使用,並且對於現有的服務器,若是它不支持 Servlet 的話,要加上這部分功能也每每是免費的(或只須要極少的投資)。

與 JSP 比較

JSP 和 Servlet 的區別到底在應用上有哪些體現,不少人搞不清楚。簡單的說,SUN 首先發展出 Servlet,其功能比較強勁,體系設計也很先進,只是,它輸出 HTML 語句仍是採用了老的 CGI 方式,是一句一句輸出,因此,編寫和修改 HTML 很是不方便。
Java Server Pages(JSP)是一種實現普通靜態HTML 和動態 HTML 混合編碼的技術,JSP 並無增長任何本質上不能用 Servlet 實現的功能。可是,在 JSP 中編寫靜態HTML 更加方便,沒必要再用 println語 句來輸出每一行 HTML 代碼。更重要的是,藉助內容和外觀的分離,頁面製做中不一樣性質的任務能夠方便地分開:好比,由頁面設計者進行 HTML設計,同時留出供 Servlet 程序員插入動態內容的空間。
後來 SUN 推出了相似於 ASP 的鑲嵌型的 JSP,把 JSP TAG 鑲嵌到 HTML 語句中,這樣,就大大簡化和方便了網頁的設計和修改。新型的網絡語言如 ASP,PHP,JSP 都是鑲嵌型的語言。 這是 JSP 和 Servlet 區別的運做原理層面。
從網絡三層結構的角度看 JSP 和 Servlet 的區別,一個網絡項目最少分三層:data layer(數據層),business layer(業務層),presentation layer(表現層)。固然也能夠更復雜。Servlet 用來寫 business layer 是很強大的,可是對於寫 presentation layer 就很不方便。JSP 則主要是爲了方便寫 presentation layer 而設計的。固然也能夠寫 business layer。寫慣了 ASPPHP,CGI的朋友,常常會不自覺的把 presentation layer 和 business layer 混在一塊兒。
根據 SUN 本身的推薦,JSP中應該僅僅存放與 presentation layer 有關的東西,也就是說,只放輸出 HTML 網頁的部分。而全部的數據計算,數據分析,數據庫聯結處理,通通是屬於 business layer,應該放在 Java BEANS 中。經過 JSP 調用 Java BEANS,實現兩層的整合。
實際上,微軟前不久推出的 DNA 技術,簡單說,就是 ASP+COM/DCOM 技術。與J SP+BEANS 徹底相似,全部的 presentation layer 由 ASP 完成,全部的 business layer 由 COM/DCOM 完成。經過調用,實現整合。
爲何要採用這些組件技術呢?由於單純的 ASP/JSP 語言是很是低效率執行的,若是出現大量用戶點擊,純 SCRIPT 語言很快就到達了他的功能上限,而組件技術就能大幅度提升功能上限,加快執行速度。
另一方面,純 SCRIPT 語言將 presentation layer 和 business layer 混在一塊兒,形成修改不方便,而且代碼不能重複利用。若是想修改一個地方,常常會牽涉到十幾頁 code,採用組件技術就只改組件就能夠了。
綜上所述,Servlet 是一個早期的不完善的產品,寫 business layer 很好,寫 presentation layer 就很臭,而且兩層混雜。
因此,推出JSP+BEAN,用 JSP 寫 presentation layer,用 BEAN 寫 business layer。SUN 本身的意思也是未來用 JSP 替代 Servlet。這是技術更新方面 JSP 和 Servlet 的區別。
但是,這不是說,學了 Servlet 沒用,實際上,你仍是應該從 Servlet 入門,再上 JSP,再上 JSP+BEAN。
強調的是:學了JSP,不會用 Java BEAN 並進行整合,等於沒學。你們多花點力氣在 JSP+BEAN 上。
咱們能夠看到,當 ASP+COM 和 JSP+BEAN 都採用組件技術後,全部的組件都是先進行編譯,並駐留內存,而後快速執行。因此,你們常常吹的 Servlet/JSP 先編譯駐內存後執行的速度優點就沒有了。
反之,ASP+COM+IIS+NT 緊密整合,應該會有較大的速度優點呈現。並且,ASP+COM+IIS+NT 開發效率很是高,雖然bug 不少。
那麼,爲何還用 JSP+BEAN?由於 Java 實在前途遠大。微軟分拆後,操做系統將羣雄並起,應用軟件的開發商一定要找一個通用開發語言進行開發,Java 一統天下的時機就到了。若是微軟分拆順利,從中分出的應用軟件公司將成爲 Java 的新領導者。目前的 Java 大頭 SUN 和 IBM 都死氣沉沉,使人失望。但願新公司能注入新活力。不過,新公司頗有可能和舊 SUN 展開 Java 標準大戰,雙方各自制定標準,影響 Java 跨平臺。
簡單分析了一下 JSP 和 Servlet 的區別和 Java Web 開發方面的發展。隨着機器速度愈來愈快,Java 的速度劣勢很快就能夠被克服。

新增功能

編輯

Servlet 2.2

:引入了 self-contained Web applications 的概念。

servlet 2.3

: 2000年10月份出來
Servlet API 2.3中最重大的改變是增長了 filters
Servlet 2.3 增長了 filters 和 filter chains 的功能。引入了 context 和 session listeners 的概念,當 context 或 session 被初始化或者被將要被釋放的時候,和當向 context 或 session 中綁定屬性或解除綁定的時候,能夠對類進行監測。

servlet 2.4

: 2003年11月份出來
Servlet 2.4 加入了幾個引發關注的特性,沒有特別突出的新內容,而是花費了更多的功夫在推敲和闡明之前存在的一些特性上,對一些不嚴謹的地方進行了校驗。
Servlet 2.4 增長了新的最低需求,新的監測 request 的方法,新的處理 response 的方法,新的國際化支持,RequestDispatcher 的幾個處理,新的 request listener 類,session 的描述,和一個新的基於 Schema 的並擁有 J2EE 元素的發佈描述符。這份文檔規範全面而嚴格的進行了修訂,除去了一些可能會影響到跨平臺發佈的模糊不清的因素。總而言之,這份規範增長了四個新類,七個新 方法,一個新常量,再也不推薦使用一個類。
注意:改成 Schema 後主要增強了兩項功能:
(1) 元素不依照順序設定;
(2) 更強大的驗證機制。
主要體如今:
a.檢查元素的值是否爲合法的值
b.檢查元素的值是否爲合法的文字字符或者數字字符
c.檢查 Servlet, Filter, EJB-ref 等等元素的名稱是否惟一
2.新增 Filter 四種設定:REQUEST、FORWARD、INCLUDE 和 ERROR。
3.新增 Request Listener、Event和Request Attribute Listener、Event。
4.取消 SingleThreadModel 接口。當 Servlet 實現 SingleThreadModel 接口時,它能確保同時間內,只能有一個 thread 執行此 Servlet。
5.<welcome-file-list>能夠爲Servlet。
6.ServletRequest接口新增一些方法。
public String getLocalName();
public String getLocalAddr();
public int getLocalPort();
public int getRemotePort()

Servlet 2.5

2005 年 9 月發佈 Servlet 2.5
Servlet 2.5 一些變化的介紹:
1) 基於最新的 J2SE 5.0 開發的。
2) 支持 annotations 。
3) web.xml 中的幾處配置更加方便。
4) 去除了少數的限制。
5) 優化了一些實例
Servlet 的各個版本對監聽器的變化有:
(1) Servlet 2.2 和 jsp1.1
新增Listener:HttpSessionBindingListener
新增Event: HttpSessionBindingEvent
(2) Servlet 2.3 和 jsp1.2
新增Listener:ServletContextListener,ServletContextAttributeListener
,HttpSessionListener,HttpSessionActivationListener,HttpSessionAttributeListener
新增Event: ServletContextEvent,ServletContextAttributeEvent,HttpSessionEvent
(3) Servlet 2.4 和 jsp2.0
新增Listener:ServletRequestListener,ServletRequestAttribureListener
新增Event: ServletRequestEvent,ServletRequestAttributeEvent

Servlet 3.0

Servlet 3.0 做爲 Java EE 6 規範體系中一員 [1]   ,隨着 Java EE 6 規範一塊兒發佈。該版本在前一版本(Servlet 2.5)的基礎上提供了若干新特性用於簡化 Web 應用的開發和部署。其中有幾項特性的引入讓開發者感到很是興奮,同時也得到了 Java 社區的一片讚譽之聲: [2]  
  1. 異 步處理支持:有了該特性,Servlet 線程再也不須要一直阻塞,直到業務處理完畢才能再輸出響應,最後才結束該 Servlet 線程。在接收到請求以後,Servlet 線程能夠將耗時的操做委派給另外一個線程來完成,本身在不生成響應的狀況下返回至容器。針對業務處理較耗時的狀況,這將大大減小服務器資源的佔用,而且提升 併發處理速度。 [2]  
  2. 新增的註解支持:該版本新增了若干註解,用於簡化 Servlet、過濾器(Filter)和監聽器(Listener)的聲明,這使得 web.xml 部署描述文件從該版本開始再也不是必選的了。 [2]  
  3. 可 插性支持:熟悉 Struts2 的開發者必定會對其經過插件的方式與包括 Spring 在內的各類經常使用框架的整合特性記憶猶新。將相應的插件封裝成 JAR 包並放在類路徑下,Struts2 運行時便能自動加載這些插件。如今 Servlet 3.0 提供了相似的特性,開發者能夠經過插件的方式很方便的擴充已有 Web 應用的功能,而不須要修改原有的應用。 [2]  

Servlet 4.0草案

從3.1到4.0將是對Servlet 協議的一次大改動,而改動的關鍵之處在於對HTTP/2的支持。HTTP2將是是繼上世紀末HTTP1.1協議規範化以來首個HTTP協議新版本,相對於 HTTP1.1,HTTP2將帶來許多的加強。在草案提議中,Shing Wai列舉出了一些HTTP2的新特性,而這些特性也正是他但願在Servlet 4.0 API中實現並暴露給用戶的新功能,這些新特性以下: [3]  
1.請求/響應複用(Request/Response multiplexing)
  2.流的優先級(Stream Prioritization)
  3.服務器推送(Server Push)
  4.HTTP1.1升級(Upgrade from HTTP 1.1) [3]  

規範

編輯
1.簡化開發
2.便於部署
3.支持 Web2.0 原則
爲了簡化開發流程,Servlet 3.0 引入了註解(annotation),這使得 web 部署描述符 web.xml 再也不是必須的選擇。
Pluggability 可插入性
當使用任何第三方的框架,如 Struts,JSF 或 Spring,咱們都須要在 web.xml 中添加對應的 Servlet 的入口。這使得 web 描述符笨重而難以維護。Servlet3.0 的新的可插入特性使得 web 應用程序模塊化而易於維護。經過 web fragment 實現的可插入性減輕了開發人員的負擔,不須要再在 web.xml 中配置不少的 Servlet 入口。
Asynchronous Processing 異步處理
另一個顯著的改變就是 Servlet 3.0 支持異步處理,這對 AJAX 應用程序很是有用。當一個 Servlet 建立一個線程來處理某些請求的時候,如查詢數據庫或消息鏈接,這個線程要等待直到得到所須要的資源纔可以執行其餘的操做。異步處理經過運行線程執行其餘的 操做來避免了這種阻塞。
Apart from the features mentioned here, several other enhancements have been made to the existing API. The sections towards the end of the article will explore these features one by one in detail.
除了這些新特性以外, Servlet 3.0對已有的 API 也作了一些改進,在本文的最後咱們會作介紹。
Annotations in Servlet Servlet 中使用註解
Servlet 3.0 的一個主要的改變就是支持註解。使用註解來定義 Servlet 和 filter 使得咱們不用在 web.xml 中定義相應的入口。
@WebServlet
@WebServlet 用來定義 web 應用程序中的一個 Servlet。這個註解能夠應用於繼承了 HttpServlet。這個註解有多個屬性,例如 name,urlPattern, initParams,咱們可使用者的屬性來定義 Servlet 的行爲。urlPattern 屬性是必須指定的。

編程接口

編輯
HTTPServlet 使用一個 HTML 表單來發送和接收數據。要建立一個 HTTPServlet,請擴展 HttpServlet 類, 該類是用專門的方法來處理 HTML 表單的 GenericServlet 的一個子類。 HTML 表單是由 <form> 和 </form> 標記定義的。表單中典型地包含輸入字段(如文本輸入字段、 複選框單選按鈕和選擇列表)和用於提交數據的按鈕。當提交信息時,它們還指定 服務器應執行哪個Servlet(或其它的程序)。 HttpServlet 類包含 init()、destroy()、service() 等方法。其中 init() 和 destroy() 方法是 繼承的。
(1) init() 方法
在 Servlet 的生命期中,僅執行一次 init() 方法。它是在服務器裝入 Servlet 時執行的。 能夠 配置服務器,以在啓動服務器或客戶機首次訪問 Servlet 時裝入 Servlet。 不管有多少客戶機訪問 Servlet,都不會重複執行 init() 。
缺省的 init() 方法一般是符合要求的,但也能夠用定製 init() 方法來覆蓋它,典型的是管理 服務器端 資源。 例如,可能編寫一個定製 init() 來只用於一次裝入 GIF 圖像,改進 Servlet 返回 GIF 圖像和含有多個客戶機請求的性能。另外一個示例是初始化數據庫鏈接。缺省的 init() 方法設置了 Servlet 的初始化參數,並用它的 ServletConfig 對象參數來啓動配置, 所以全部覆蓋 init() 方法的 Servlet 應調用 super.init() 以確保仍然執行這些任務。在調用 service() 方法以前,應確保已完成了 init() 方法。
(2) service() 方法
service() 方法是 Servlet 的核心。每當一個客戶請求一個HttpServlet 對象,該對象的service() 方法就要被調用,並且傳遞給這個方法一個"請求"(ServletRequest)對象和一個"響應"(ServletResponse)對象做爲參數。 在 HttpServlet 中已存在 service() 方法。缺省的服務功能是調用與 HTTP 請求的方法相應的 do 功能。例如, 若是 HTTP 請求方法爲 GET,則缺省狀況下就調用 doGet() 。Servlet 應該爲 Servlet 支持的 HTTP 方法覆蓋 do 功能。由於 HttpServlet.service() 方法會檢查請求方法是否調用了適當的處理方法,沒必要要覆蓋 service() 方法。只需覆蓋相應的 do 方法就能夠了。
Servlet 的響應能夠是下列幾種類型:
一個輸出流,瀏覽器根據它的內容類型(如 text/html)進行解釋。
一個 HTTP 錯誤響應,重定向到另外一個 URL、servlet、JSP。
(3) doGet() 方法
當一個客戶經過 HTML 表單發出一個 HTTP GET 請求或直接請求一個 URL 時,doGet() 方法被調用。與 GET 請求相關的參數添加到 URL 的後面,並與這個請求一塊兒發送。當不會修改 服務器端的數據時,應該使用 doGet() 方法。
(4) doPost() 方法
當一個客戶經過 HTML 表單發出一個 HTTP POST 請求時,doPost() 方法被調用。與 POST 請求相關的參數做爲一個單獨的 HTTP 請求從瀏覽器發送到服務器。當須要修改服務器端的數據時,應該使用 doPost() 方法。
(5) destroy() 方法
destroy() 方法僅執行一次,即在服務器中止且卸裝 Servlet 時執行該方法。典型的,將 Servlet 做爲服務器進程的一部分來關閉。缺省的 destroy() 方法一般是符合要求的,但也能夠覆蓋它,典型的是管理服務器端資源。例如,若是 Servlet 在運行時會累計統計數據,則能夠編寫一個 destroy() 方法,該方法用於在未裝入 Servlet 時將統計數字保存在文件中。另外一個示例是關閉數據庫鏈接。
服務器卸 裝 Servlet 時,將在全部 service() 方法調用完成後,或在指定的時間間隔事後調用 destroy() 方法。一個 Servlet 在運行 service() 方法時可能會產生其它的線程,所以請確認在調用 destroy() 方法時,這些線程已終止或完成。
(6) getServletConfig() 方法
getServletConfig() 方法返回一個 ServletConfig 對象,該對象用來返回初始化參數和 ServletContext。ServletContext 接口提供有關 servlet 的環境信息。
(7) getServletInfo() 方法
getServletInfo() 方法是一個可選的方法,它提供有關 servlet 的信息,如做者、版本、版權。
服務器調用 sevlet 的 service()、doGet() 和 doPost() 這三個方法時,均須要 「請求」和「響應」對象做爲參數。「請求」對象提供有關請求的信息,而「響應」對象提供了一個將響應信息返回給瀏覽器的一個通訊途徑。
javax.servlet 軟件包中的相關類爲 ServletResponse 和 ServletRequest,而 javax.servlet. http 軟件包中的相關類爲 HttpServletRequest 和 HttpServletResponse。Servlet 經過這些對象與 服務器通訊並最終與客戶端通訊。Servlet 能經過調用"請求"對象的方法獲知客戶端環境,服務器環境的信息和全部由客戶機提供的信息。Servlet 能夠調用「響應」對象的方法發送響應,該響應是準備發回客戶端的。

常見容器

編輯
Tomcat, Jetty, resin, Oracle Application server, WebLogic Server, Glassfish, Websphere, JBoss 等等。(提供了 Servlet 功能的服務器,叫作 Servlet 容器。對 web 程序來講,Servlet 容器的做用就至關於桌面程序裏操做系統的做用,都是提供一些編程基礎設施)

建議

編輯
在 Web 應用程序中,一個 Servlet 在一個時刻可能被多個用戶同時訪問。這時 Web 容器將爲每一個用戶建立一個線程來執行 Servlet。若是 Servlet 不涉及共享資源的問題,沒必要關心多線程問題。但若是 Servlet 須要共享資源,須要保證 Servlet 是 線程安全的。
下面是編寫線程安全的 Servlet 的一些建議:
(1)用方法的局部變量保存請求中的專有數據。對方法中定義的局部變量,進入方法的每一個線程都有本身的一份方法變量拷貝。任何線程都不會修改其餘線程的局部變量。若是要在不一樣的請求之間共享數據,應該使用會話來共享這類數據。
(2)只用 Servlet的成員變量來存放那些不會改變的數據。有些數據在 Servlet 生命週期中不發生任何變化,一般是在初始時肯定的,這些數據可使用成員變量保存,如數據庫鏈接名稱、其餘資源的路徑等。
(3)對可能被請求修改的成員變量同步。有時數據成員變量或者環境屬性可能被請求修改。當訪問這些數據時應該對它們同步,以免多個線程同時修改這些數據。
(4)若是 Servlet 訪問外部資源,那麼須要同步訪問這些資源。例如,假設 Servlet 要從文件中讀寫數據。當一個線程讀寫一個文件時,其餘線程也可能正在讀寫這個文件。文件訪問自己不是線程安全的,因此必須編寫同步訪問這些資源的代碼。在 編寫線程安全的 Servlet 時,下面兩種方法是不該該使用的:
(1)在 Servlet API 中提供了一個 SingleThreadModel 接口,實現這個接口的 Servlet 在被多個客戶請求時一個時刻只有一個線程運行。這個接口已被標記不推薦使用。
(2)對 doGet() 或doPost() 方法同步。若是必須在 Servlet 中使用同步代碼,應儘可能在最小的代碼塊範圍上進行同步。同步代碼越小,Servlet 執行得才越好。 [4]  
相關文章
相關標籤/搜索