[ 永遠的UNIX::UNIX技術資料的寶庫 ]   GB | BIG5

首頁 > 編程技術 > Java > 正文
JAVA Servlets簡介
本文出自: www.dukejava.com 作者:javaduke (2001-05-30 12:10:00)
  Servlets是JAVA 2.0中新增的一個全新功能, Servlets是一種採用JAVA技術來實現CGI功能的一種技術。Servlet和CGI一樣都是運行在WEB服務器上,用來生成WEB頁面。 
一、JAVA Servlets為什優傳統的CGI 
  JAVA Servlets比傳統的CGI或其它CGI類似替代技術來說,效率更高,使用更方便,功能更強大,更小巧也更便宜: 

1)效率,傳統CGI對每一個HTTP請求都要產生一個新的進程。如果某個CGI程序是一個執行非常快的操作,打開進程的時間也許佔用了大部分執行時間。而對JAVA Servlets來說,在JAVA 虛擬機上,每一個請求由一個'小'JAVA線程(thread)響應,而不是一個`大`操作系統進程。類似地,傳統CGI如果對同一個CGI程序有N個同時請求,這個CGI程序的代碼將被導入內存N次。JAVA Servlets 產生N個線程,但只有一個JAVA Servlets CLASS的copy。同時JAVA Servlets比CGI有更多的優化選擇,象預先計算,打開數據庫連接等。 

2)方便,JAVA Servlets能自動的粘貼和解碼HTML表單數據,讀和設置HTTP頭,處理COOKIES,跟蹤SESSIONS,等其它大量功能。 

3)強大的功能,JAVA Servlets可以很容易的實現對CGI來說是不可能或很困難的事務。JAVA Servlets能直接和服務器進行通訊而CGI是不能的。 

4)JAVA Servlets之間能共享數據,很容易實現諸如數據庫連接池。它能方便的實現管理從REQUEST到REQUEST請求,簡化SESSION和獲取前一頁面。而CGI之間通訊差,由每個CGI程序的調用都開始一個新的進程,調用間通訊通常要通過文件進行,因而相當緩慢。同一台服務器上的不同CGI程序之間的通訊也相當麻煩。 

5)調用時間:CGI程序是作為單獨過程運行的,通常調用時間較長,這個間接成本在每次調用的時候都要發生。在使用解釋器的時候調用時間會更長。而內存中的servlet可以非常迅速地加載。 

6)安全:有些CGI版本有明顯的安全弱點。即使是使用最新的標準和PERL等語言,系統也沒有基本安全框架,而要靠一組事實上的規則。而java定義有完整的安全機制,包括ssl,ca認証,安全政策等規范。 

7)小巧,JAVA Servlets使用JAVA編寫,遵循標準API。它能直接或借助插件在幾乎所有WEB服務器上運行。 

8)價格低,顯然,有很多都是FREE。 

Servlet的一些應用范圍: 

1) 用處理HTML表單:通過HTTP產生POSTed數據,包括買賣訂單或信用卡數據。因此servlet可以成為訂單處理系統的一部分,和產品存貨數據庫一道工作,也許可以用在在線支付系統上。 

2)允許人們之間的合作:一個servlet能並發處理多個請求;他們可以使用在諸如在線會議這樣的同步請求支持系統。 

3) 轉送請求:Servlet可以轉送請求給其他的服務器和servlets。這就允許在鏡象同樣內容的幾個服務器之間平衡負載。按照任務類型或組織范圍,可以允許被用來在幾個服務器中劃分邏輯上的服務器。 

4) servlet 編寫者們可以定義彼此之間共同工作的激活代理,每個代理者是一個servlet,而且代理者能夠在他們之間傳送數據。 


二、Servlet的結構 

  在具體掌握servlet之前,須對java語言有所了解。下面是基您了解java基礎上的,在Servlet API中最重要的是Servlet interface. 所有的servlets implement(執行)這個interface, 方式多種:或者是直接的,或者通過擴展類(class)執行它,如 HttpServlet。 這個Servlet interface 提供安排servlet與客戶端聯系的方法. Servlet 編寫者可以在他們開發 servlet程序時提供更多一些或所有的這樣方法. 

  當一個servlet接收來自客戶端的調用請求, 它接收兩個對象: 一個是ServletRequest,另外一個是ServletResponse. 這個ServletRequest類概括從客戶端到服務器之間的聯系, 而 ServletResponse類概括從servlet返回客戶端的聯系. 

  ServletRequest interface 可以獲取到這樣一些信息如由客戶端傳送的闡述名稱,客戶端正在使用的協議, 產生請求並且接收請求的服務器遠端主機名. 它也提供獲取數據流的servlet, ServletInputStream, 這些數據是客戶端引用中使用HTTP POST 和 PUT 方法遞交的. 一個ServletRequest的子類可以讓 servlet獲取更多的協議特性數據. 例如: HttpServletRequest 包含獲取 HTTP-specific頭部信息的方法. 

  ServletResponse interface 給出相應客戶端的servlet方法. 它允許servlet 設置內容長度和回應的mime類型, 並且提供輸出流, ServletOutputStream, 通過編寫者可以發回相應數據. ServletResponse子類可以給出更多 protocol-specific容量的信息。 例如: HttpServletResponse 包含允許servlet 操作HTTP-specific頭部信息的方法. 

  上面有關類和 interfaces描述構成了一個基本的Servlet框架. HTTP servlets有一些附加的可以提供session-tracking capabilities的方法. servlet編寫者可以用這些API在有他人操作時維護servlet與客戶端之間的狀態. 

三、Servlet的接口 

  Servlet 從javax包的httpservlet類擴展,在HttpServlet中加入了一些附加的方法,這些方法可以被協助處理HTTP 基本請求的HttpServlet類中的方法service自動地調用。這些方法有: 

doGet 用來處理HTTP的GET請求。 
  這個GET操作僅僅允許客戶從HTTP server上"取得"(GET)資源。重載此方法的用戶自動允許支持方法HEAD。這個GET操作被認為是安全的,沒有任何的負面影響,對用戶來說是很可靠的。比如,大多數的正規查詢都沒有副作用。打算改變存儲數據的請求必須用其他的HTTP方法。這要求方法也必須是個安全的操作。方法doGet的缺省執行將返回一個HTTP的BAD_REQUEST錯誤。 
方法doGet的格式: 
protected void doGet(HttpServletResquest request, 
HttpServletResponse response) 
throws ServletException, 
IOException; 


doPost 用來處理HTTP的POST請求。 
  這個POST操作包含了在必須通過此servlet執行的請求中的數據。由它不能立即取得資源,故對那些涉及到安全性的用戶來說,通過POST請求操作會有一些副作用。 
  方法doPost的缺省執行將返回一個HTTP的BAD_REQUEST錯誤。當編寫servlet時,為了支持POST操作必須在子類HttpServlet中實現(implement)此方法。 
此方法的格式: 
protected void doPost(HttpServletResquest request, 
HttpServletResponse response) 
throws ServletException, 
IOException; 


doPut用來處理HTTP的PUT請求。 
  此PUT操作模擬通過FTP發送一個文件。對那些涉及到安全性的用戶來說,通過PUT請求操作也會有一些副作用。 
此方法的格式: 
protected void doPut(HttpServletResquest request, 
HttpServletResponse response) 
throws ServletException, 
IOException; 


doDelete用來處理HTTP的DELETE請求。 
  此操作允許客戶端請求一個從server移出的URL。對那些涉及到安全性的用戶來說,通過DELETE請求操作會有一些副作用。 
方法doDelete的缺省執行將返回一個HTTP的BAD_REQUEST錯誤。當編寫servlet時,為了支持DELETE操作,必須在子類HttpServlet中實現(implement)此方法。 
此方法的格式: 
protected void doDelete (HttpServletResquest request, 
HttpServletResponse response) 
throws ServletException,IOException; 


doHead 用來處理HTTP的HEAD請求。 
  缺省地,它會在無條件的GET方法執行時期中運行,但是不返回任何數據到客戶端。只返回包含內容信息的長度的header。由用到GET操作,此方法應該是很安全的(沒有副作用)也是可重復使用的。此方法的缺省實現(implement)自動地處理了HTTPDE的HEAD操作並且不需要通過一個子類實現(implement)。 
此方法的格式: 
protected void doHead (HttpServletResquest request, 
HttpServletResponse response) 
throws ServletException, 
IOException; 


doOptions用來處理HTTP的OPTIONS請求。 
  此操作自動地決定支持什HTTP方法。比如說,如果一個servlet的作者創建HttpServlet的子類並重載方法doGet,然方法doOptions會返回下面的header: 
Allow:GET,HEAD,TRACE,OPTIONS 
一般不需要重載方法doOptions。 
此方法的格式: 
protected void doOptions (HttpServletResquest request, HttpServletResponse response) 
throws ServletException, 
IOException; 


doTrace用來處理HTTP的TRACE請求。 
此方法的缺省執行產生一個包含所有在trace請求中的herder的信息的應答(response)。 
在開發servlet時,多數情況下需要重載此方法。 
此方法的格式: 
protected void doTrace (HttpServletResquest request, 
HttpServletResponse response) 
throws ServletException, 
IOException; 
在開發以HTTP為基礎的servlet中,Servlet開發者關心方法doGet和方法doPost即可。 

四、Servlet的生命周期 

  如果你寫過java的小應用程序(Apple),那Servlet對你來說就不會太難,SZ更為簡單因為Servlet不用考慮圖形界面的應用,而與小應用程序一樣,Servlet與有一個生命周期。Servlet的生命周期是當服務器裝載運行servlets:接收來自客戶端的多個請求並且返回數據給客戶端. 然在刪除移開servlets.下面詳細描述如下: 

1)初始化時期 
  當一個服務器裝載servlet時, 它運行servlet的 init() 方法. 

public void init(ServletConfig config) throws ServletException 
{ super.init(); //一些初始化的操作,如數據庫的連接 } 

  需要記住的是一定要在init()結束時調用super.init().init()方法不能反復調用,一旦調用就是重裝載servlet. 直到服務器調用destroy方法卸載servlet才能再調用. 

2)Servlet的執行時期 

  在服務器裝載初始化servlet, servlet就能夠處理客戶端的請求. 用 service 方法做到這一點. 每個客戶端請求有它自己service方法: 這些方法接收客戶端請求, 並且發回相應的響應.Servlets能同時運行多個service. 這是很重要的, 這樣, service方法可以按一個thread-safe 樣式編寫. 如:service方法更新servlet對象中的一個字段field, 這個字段可以同時存取的. 假如某個服務器不能同時並發運行 service方法,也可以用SingleThreadModel interface. 這個 interface 保証不會有兩個以上的線程threads並發運行. 在Servlet執行期間其最多的應用是處理客戶端的請求並產生一個網頁。其代碼如下: 

PrintWriter out = response.getWriter(); 
out.println(""); 
out.println(""# Servlet "); 
out.println(""); 
out.println("Hello World"); 
out.println(""); 
out.close(); 

3)Servlet結束時期 

  Servlets一直運行到他們被服務器卸載。在結束的時需地收回在init()方法中使用的資源,在Servlet中是通過destory()方法來實現的。 
public void destroy() 

//回收在init()中啟用的資源,如關閉數據庫的連接等。 


五、Servlet應用實例 

  現在我們來一個簡單的例子來說明Servlet的應用,其完全成的功能是讀取表單的內容並輸出到瀏覽器上。 

test.html test.java 
 
表單應用例子 
 
 
 
 

姓名: 
 

 

 Email: 
 

 

意見: 
 

 

 
 

 
 
 
 
import javax.servlet.*; 
import javax.servlet.http.*; 
import java.io.*; 
import java.util.*; 


public class test extends HttpServlet { 
private DBConnectionManager connMgr; 
//Initialize global variables 
public void init(ServletConfig config) throws ServletException { 
super.init(config); 



//Process the HTTP Get request 
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
response.setContentType("text/html"); 
String name=request.getParameter("name"); 
String mail=request.getParameter("mail"); 
ServletOutputStream out=response.getOutputStream (); 
out.println(""); 
out.println("servlet表單應用例子"); 
out.println(""); 
out.println(name); 
out.println("
"); 
out.println(mail); 
out.println(""); 
out.close(); 


//Process the HTTP Post request 
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
doGet(request,response); 


public void destroy() { 





把test.html放入web服務器的根目錄下,而test.java 這個servlet編譯成class一般都放在web服務器的class目錄下,在resin中是放在doc\WEB-INF\classes目錄下,而resin能在運行時自動編譯,報所以直接報test.java 放在doc\WEB-INF\classes目錄下即可。 
原作者:javaduke
來 源:www.dukejava.com

 


(http://www.fanqiang.com)
    進入【UNIX論壇

相關文章
 

★  樊強制作 歡迎分享  ★