Java Servlet技術

第四課 Java Servlet技術

   4.1 Servlet簡介
   4.2 創建HTTP Servlet
   4.3 調用 Servlet

  4.1 Servlet簡介
  1.Servlet 是什麼?
  Servlet是使用Java Servlet 應用程序設計接口(API)及相關類和方法的 Java 程序。除了 Java Servlet API,Servlet 還可以使用用以擴展和添加到 API 的 Java 類軟件包。Servlet 在啓用 Java 的 Web 服務器上或應用服務器上運行並擴展了該服務器的能力。Java servlet對於Web服務器就好象Java applet對於Web瀏覽器。Servlet裝入Web服務器並在Web服務器內執行,而applet裝入Web瀏覽器並在Web瀏覽器內執行。Java Servlet API 定義了一個servlet 和Java使能的服務器之間的一個標準接口,這使得Servlets具有跨服務器平臺的特性。
  Servlet 通過創建一個框架來擴展服務器的能力,以提供在 Web 上進行請求和響應服務。當客戶機發送請求至服務器時,服務器可以將請求信息發送給 Servlet,並讓 Servlet 建立起服務器返回給客戶機的響應。 當啓動 Web 服務器或客戶機第一次請求服務時,可以自動裝入 Servlet。裝入後, Servlet 繼續運行直到其它客戶機發出請求。Servlet 的功能涉及範圍很廣。例如,Servlet 可完成如下功能:
  (1) 創建並返回一個包含基於客戶請求性質的動態內容的完整的 HTML頁面。
  (2) 創建可嵌入到現有 HTML 頁面中的一部分 HTML 頁面(HTML 片段)。
  (3) 與其它服務器資源(包括數據庫和基於 Java 的應用程序)進行通信。
  (4) 用多個客戶機處理連接,接收多個客戶機的輸入,並將結果廣播到多個客戶機上。例如,Servlet 可以是多參與者的遊戲服務器。
  (5) 當允許在單連接方式下傳送數據的情況下,在瀏覽器上打開服務器至applet的新連接,並將該連
接保持在打開狀態。當允許客戶機和服務器簡單、高效地執行會話的情況下,applet也可以啓動客戶瀏覽器和服務器之間的連接。可以通過定製協議或標準(如 IIOP)進行通信。
  (6) 對特殊的處理採用 MIME 類型過濾數據,例如圖像轉換和服務器端包括(SSI)。
  (7) 將定製的處理提供給所有服務器的標準例行程序。例如,Servlet 可以修改如何認證用戶。
  2.Servlet 的生命週期
  Servlet 的生命週期始於將它裝入 Web 服務器的內存時,並在終止或重新裝入 Servlet 時結束。
  (1) 初始化
  在下列時刻裝入 Servlet:
 如果已配置自動裝入選項,則在啓動服務器時自動裝入
 在服務器啓動後,客戶機首次向 Servlet 發出請求時
 重新裝入 Servlet 時裝入 Servlet 後,服務器創建一個 Servlet 實例並且調用 Servlet 的 init() 方法。在初始化階段,Servlet 初始化參數被傳遞給 Servlet 配置對象。
  (2) 請求處理
  對於到達服務器的客戶機請求,服務器創建特定於請求的一個“請求”對象和一個“響應”對象。服務器調用 Servlet 的 service() 方法,該方法用於傳遞“請求”和“響應”對象。service() 方法從“請求”對象獲得請求信息、處理該請求並用“響應”對象的方法以將響應傳回客戶機。service() 方法可以調用其它方法來處理請求,例如 doGet()、doPost() 或其它的方法。
  (3) 終止
  當服務器不再需要 Servlet, 或重新裝入 Servlet 的新實例時,服務器會調用 Servlet 的 destroy() 方法。
  3. Java Servlet API
  Java Servlet 開發工具(JSDK)提供了多個軟件包,在編寫 Servlet 時需要用到這些軟件包。其中包括兩個用於所有 Servlet 的基本軟件包:javax.servlet 和 javax.servlet.http。可從sun公司的Web站點下載 Java Servlet 開發工具。 下面主要介紹javax.servlet.http提供的HTTP Servlet應用編程接口。
  HTTP Servlet 使用一個 HTML 表格來發送和接收數據。要創建一個 HTTP Servlet,請擴展 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 方法就可以了。
 當一個客戶通過HTML 表單發出一個HTTP POST請求時,doPost()方法被調用。與POST請求相關的參數作爲一個單獨的HTTP 請求從瀏覽器發送到服務器。當需要修改服務器端的數據時,應該使用doPost()方法。
 當一個客戶通過HTML 表單發出一個HTTP GET請求或直接請求一個URL時,doGet()方法被調用。與GET請求相關的參數添加到URL的後面,並與這個請求一起發送。當不會修改服務器端的數據時,應該使用doGet()方法。
  Servlet的響應可以是下列幾種類型:
  一個輸出流,瀏覽器根據它的內容類型(如text/HTML)進行解釋。
  一個HTTP錯誤響應, 重定向到另一個URL、servlet、JSP。
  (3) destroy() 方法
  destroy() 方法僅執行一次,即在服務器停止且卸裝Servlet 時執行該方法。典型的,將 Servlet 作爲服務器進程的一部分來關閉。缺省的 destroy() 方法通常是符合要求的,但也可以覆蓋它,典型的是管理服務器端資源。例如,如果 Servlet 在運行時會累計統計數據,則可以編寫一個 destroy() 方法,該方法用於在未裝入 Servlet 時將統計數字保存在文件中。另一個示例是關閉數據庫連接。
當服務器卸裝 Servlet 時,將在所有 service() 方法調用完成後,或在指定的時間間隔過後調用 destroy() 方法。一個Servlet 在運行service() 方法時可能會產生其它的線程,因此請確認在調用 destroy() 方法時,這些線程已終止或完成。
  (4) GetServletConfig()方法
  GetServletConfig()方法返回一個 ServletConfig 對象,該對象用來返回初始化參數和  ServletContext。ServletContext 接口提供有關servlet 的環境信息。
  (5) GetServletInfo()方法
  GetServletInfo()方法是一個可選的方法,它提供有關servlet 的信息,如作者、版本、版權。
  當服務器調用sevlet 的Service()、doGet()和doPost()這三個方法時,均需要 “請求”和“響應”對象作爲參數。“請求”對象提供有關請求的信息,而“響應”對象提供了一個將響應信息返回給瀏覽器的一個通信途徑。javax.servlet 軟件包中的相關類爲ServletResponse和ServletRequest,而javax.servlet.http 軟件包中的相關類爲HttpServletRequest 和 HttpServletResponse。Servlet 通過這些對象與服務器通信並最終與客戶機通信。Servlet 能通過調用“請求”對象的方法獲知客戶機環境,服務器環境的信息和所有由客戶機提供的信息。Servlet 可以調用“響應”對象的方法發送響應,該響應是準備發回客戶機的。
  
4.2 創建HTTP Servlet
  創建一個 HTTP Servlet,通常涉及下列四個步驟:
  1. 擴展 HttpServlet 抽象類。
  2. 重載適當的方法。]如覆蓋(或稱爲重寫)doGet() 或doPost()方法。
  3. 如果有 HTTP 請求信息的話,獲取該信息。用 HttpServletRequest 對象來檢索 HTML 表格所
  提交的數據或 URL 上的查詢字符串。“請求”對象含有特定的方法以檢索客戶機提供的信息,有3個可用的方法:
 getParameterNames(),
 getParameter(),
 getParameterValues()。
  4. 生成 HTTP 響應。HttpServletResponse 對象生成響應,並將它返回到發出請求的客戶機上。它
的方法允許設置“請求” 標題和“響應”主體。“響應”對象還含有 getWriter() 方法以返回一個 PrintWriter 對象。使用 PrintWriter 的 print() 和 println() 方法以編寫 Servlet 響應來返回給客戶機。或者,直接使用out對象輸出有關HTML文檔內容。
  一個servlet樣例(ServletSample.java)如下:
  import java.io.*;
  import java.util.*;
  import javax.servlet.*;
  import javax.servlet.http.*;

  public class ServletSample extends HttpServlet { // 第一步: 擴展 HttpServlet 抽象類。
  
  public void doGet (HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException { // 第二步:重寫doGet()方法

  String myName = ""; // 第三步:獲取HTTP 請求信息
  java.util.Enumeration keys = request.getParameterNames();
  while (keys.hasMoreElements());
  {
  key = (String) keys.nextElement();
  if (key.equalsIgnoreCase("myName"))
  myName = request.getParameter(key);
  }
  if (myName == "")
  myName = "Hello";
  // 第四步:生成 HTTP 響應。
  response.setContentType("text/html");
  response.setHeader("Pragma", "No-cache");
  response.setDateHeader("Expires", 0);
  response.setHeader("Cache-Control", "no-cache");

  out.println("<head><title>Just a basic servlet</title></head>");
  out.println("<body>");
  out.println("<h1>Just a basic servlet</h1>");
  out.println ("<p>" + myName + ", this is a very basic servlet that writes an HTML
   page.");
  out.println ("<p>For instructions on running those samples on your WebSphere應用服務器,   "+
  "open the page:");
  out.println("<pre>http://<em>your.server.name</em>/IBMWebAs/samples/index.aspl</pre>");
  out.println("where <em>your.server.name</em> is the hostname of your WebSphere應用服
  務器.");
  out.println("</body></html>");
  out.flush();
  }
  }
  上述ServletSample類擴展 HttpServlet 抽象類、重寫doGet()方法。在重寫的doGet()方法中,獲取HTTP 請求中的一個任選的參數(myName),該參數可作爲調用的 URL 上的查詢參數傳遞到 Servlet。使用示例如下:http://your.server.name/servlet/ServletSample?myname=Michael
  
4.3 調用 Servlet
  要調用 Servlet 或 Web 應用程序,請使用下列任一種方法:由 URL 調用、在 <FORM> 標記中調用、在 <SERVLET>標記中調用、在 JSP 文件中調用、在 ASP 文件中調用。
  1. 由 URL 調用 Servlet
  這裏有兩種用 Servlet 的 URL 從瀏覽器中調用該 Servlet 的方法:
  (1) 指定 Servlet 名稱:當用 WebSphere應用服務器 管理器來將一個 Servlet 實例添加(註冊)到服務器配置中時,必須指定“Servlet 名稱”參數的值。例如,可以指定將hi作爲HelloWorldServlet 的 Servlet 名稱。要調用該 Servlet,需打開 http://your.server.name/servlet/hi。也可以指定 Servlet 和類使用同一名稱(HelloWorldServlet)。在這種情況下,將由 http://your.server.name/servlet/HelloWorldServlet 來調用 Servlet 的實例。
  (2) 指定 Servlet 別名:用 WebSphere應用服務器 管理器來配置 Servlet 別名,該別名是用於調用 Servlet 的快捷 URL。快捷 URL 中不包括 Servlet 名稱。
  2. 在 <FORM> 標記中指定 Servlet
  可以在 <FORM> 標記中調用 Servlet。HTML 格式使用戶能在 Web 頁面(即從瀏覽器)上輸入數據,並向 Servlet 提交數據。例如:
  <FORM METHOD="GET" ACTION="/servlet/myservlet">
  <OL>
  <INPUT TYPE="radio" NAME="broadcast" VALUE="am">AM<BR>
  <INPUT TYPE="radio" NAME="broadcast" VALUE="fm">FM<BR>
  </OL>
  (用於放置文本輸入區域的標記、按鈕和其它的提示符。)
  </FORM>
  ACTION 特性表明了用於調用 Servlet 的 URL。關於METHOD 的特性,如果用戶輸入的信息是通過 GET 方法向 Servlet 提交的,則 Servlet 必須優先使用 doGet() 方法。反之,如果用戶輸入的信息是通過 POST 方法向 Servlet 提交的,則 Servlet 必須優先使用 doPost() 方法。使用 GET 方法時,用戶提供的信息是查詢字符串表示的 URL 編碼。無需對 URL 進行編碼,因爲這是由表單完成的。然後 URL 編碼的查詢字符串被附加到 Servlet URL 中,則整個 URL 提交完成。URL 編碼的查詢字符串將根據用戶同可視部件之間的交互操作,將用戶所選的值同可視部件的名稱進行配對。例如,考慮前面的 HTML 代碼段將用於顯示按鈕(標記爲 AM 和 FM),如果用戶選擇 FM 按鈕,則查詢字符串將包含 name=value 的配對操作爲broadcast=fm。因爲在這種情況下,Servlet 將響應 HTTP 請求,因此 Servlet 應基於 HttpServlet 類。Servlet 應根據提交給它的查詢字符串中的用戶信息使用的 GET 或 POST 方法,而相應地使用 doGet() 或 doPost() 方法。
  3.在 <SERVLET> 標記中指定 Servlet
  當使用 <SERVLET> 標記來調用 Servlet 時,如同使用 <FORM> 標記一樣,無需創建一個完整的 HTML 頁面。作爲替代,Servlet 的輸出僅是 HTML 頁面的一部分,且被動態嵌入到原始 HTML 頁面中的其它靜態文本中。所有這些都發生在服務器上,且發送給用戶的僅是結果 HTML 頁面。建議在 Java 服務器頁面(JSP)文件中使用 <SERVLET> 標記。請參閱有關 JSP 技術
  原始 HTML 頁面中包含 <SERVLET> 和 </SERVLET> 標記。 Servlet 將在這兩個標記中被調用,且 Servlet 的響應將覆蓋這兩個標記間的所有東西和標記本身。如果用戶的瀏覽器可以看到 HTML 源文件,則用戶將看不到 <SERVLET> 和 </SERVLET> 標記。要在 Domino Go Webserver 上使用該方法,請啓用服務器上的服務器端包括功能。部分啓用過程將會涉及到添加特殊文件類型 SHTML。當 Web 服務器接收到一個擴展名爲 SHTML 的 Web 頁面請求時,它將搜索 <SERVLET> 和 </SERVLET> 標記。對於所有支持的 Web 服務器,WebSphere應用服務器 將處理 SERVLET 標記間的所有信息。下列 HTML 代碼段顯示瞭如何使用該技術。
  <SERVLET NAME="myservlet" CODE="myservlet.class" CODEBASE="url" initparm1="value">
  <PARAM NAME="parm1" VALUE="value">
  </SERVLET>
  使用 NAME 和 CODE 屬性帶來了使用上的靈活性。可以只使用其中一個屬性,也可以同時使用兩個屬性。 NAME 屬性指定了 Servlet 的名稱(使用 WebSphere應用服務器 管理器配置的),或不帶 .class 擴展名的 Servlet 類名。CODE 屬性指定了 Servlet 類名。使用 WebSphere應用服務器 時,建議指定 NAME 和 CODE,或當 NAME 指定了 Servlet 名稱時,僅指定 NAME。如果僅指定了 CODE,則會創建一個 NAME=CODE 的 Servlet 實例。裝入的 Servlet 將假設 Servlet 名稱與 NAME 屬性中指定的名稱匹配。然後,其它 SHTML 文件可以成功地使用 NAME 屬性來指定 Servlet 的名稱,並調用已裝入的 Servlet。NAME 的值可以直接在要調用 Servlet 的 URL 中使用。如果 NAME 和 CODE 都存在,且 NAME 指定了一個現有 Servlet,則通常使用 NAME 中指定的 Servlet。由於 Servlet 創建了部分 HTML 文件,所以當創建 Servlet 時,將可能會使用 HttpServlet 的一個子類,並優先使用 doGet() 方法(因爲 GET 方法是提供信息給 Servlet 的缺省方法)。另一個選項是優先使用 service() 方法。另外, CODEBASE 是可選的,它指定了裝入 Servlet 的遠程系統的 URL。請使用 WebSphere應用服務器 管理器來從 JAR 文件配置遠程 Servlet 裝入系統。
  在上述的標記示例中,initparm1 是初始化參數名,value 是該參數的值。可以指定多個“名稱-值”對的集合。利用 ServletConfig 對象(被傳遞到 Servlet 的 init() 方法中)的 getInitParameterNames() 和 getInitParameter() 方法來查找參數名和參數值的字符串數組。在示例中,parm1 是參數名,並在初始化 Servlet 後被才被設置某個值。因爲只能通過使用“請求”對象的方法來使用以 <PARAM> 標記設置的參數,所以服務器必須調用 Servlet service() 方法,以從用戶處傳遞請求。要獲得有關用戶的請求信息,請使用 getParameterNames()、getParameter() 和 getParameterValues() 方法。
  初始化參數是持續的。假設一臺客戶機通過調用一個包含某些初始化參數的 SHTML 文件來調用 Servlet。並假設第二臺客戶機通過調用第二個 SHTML 文件來調用同一個 Servlet,且該 SHTML 中未指定任何初始化參數。那麼第一次調用 Servlet 時所設置的初始化參數將一直可用,並且通過所有其它 SHTML 文件而調用的所有後繼 Servlet 都不會更改該參數。直到 Servlet 調用了 destroy() 方法後,才能重新設置初始化參數。例如,如果另一個 SHTML 文件指定了另一個不同的初始化參數值,雖然已此時已裝入了 Servlet,但該值仍將被忽略。
  4.在 JSP 文件中調用 Servlet
  可以從 JavaServer 頁面(JSP)文件中調用 Servlet。請參閱JSP技術部分。
  5.在 ASP 文件中調用 Servlet
  如果在 Microsoft Internet Information Server(IIS)上有遺留的 ASP 文件,並且無法將 ASP 文件移植成 JSP 文件時,可用 ASP 文件來調用 Servlet。在 WebSphere應用服務器 中的 ASP 支持包括一個用於嵌入 Servlet 的 ActiveX 控制,下面介紹ActiveX 控制AspToServlet 的方法和屬性。
該方法說明如下:
  (1) String ExecServletToString(String servletName);執行 ServletName,並將其輸出返回到一個字符串中。
  (2) ExecServlet(String servletName);執行 ServletName,並將其輸出直接發送至 HTML 頁面。
  (3) String VarValue(String varName);獲得一預置變量值(其它格式)。
  (4) VarValue(String varName, String newVal);設置變量值。變量佔據的總大小應小於 0.5 個千字節(Kbyte)。且僅對配置文件使用這些變量。
  其屬性如下:
 Boolean WriteHeaders;若該屬性爲真,則 Servlet 提供的標題被寫入用戶處。缺省值爲假。
 Boolean OnTest;若該屬性爲真,服務器會將消息記錄到生成的 HTML 頁面中。缺省值爲假。
  下列ASP 腳本示例是以 Microsoft Visual Basic Scripting(VBScript)書寫的。
  <%
  ' Small sample asp file to show the capabilities of the servlets and the ASP GateWay ...
  %>
  <H1> Starting the ASP->Java Servlet demo</H1>
  <%
  ' Create a Servlet gateway object and initialize it ...
  Set javaasp = Server.CreateObject("AspToServlet.AspToServlet")
  ' Setting these properties is only for the sake of demo.
  ' These are the default values ...
  javaasp.OnTest = False
  javaasp.WriteHeaders = False
  ' Add several variables ...
  javaasp.VarValue("gal") = "lag"
  javaasp.VarValue("pico")= "ocip"
  javaasp.VarValue("tal") = "lat"
  javaasp.VarValue("paz") = "zap"
  javaasp.VarValue("variable name with spaces") = "variable value with spaces"
  %>
  <BR>
  Lets check the variables
  <%
  Response.Write("variable gal = ")
  Response.Write(javaasp.VarValue("gal"))
  %>
  <BR>
  <%
  Response.Write("variable pico = " & javaasp.VarValue("pico"))
  %>
  
  <BR>
  <HR>
  <%
  galout = javaasp.ExecServletToString("SnoopServlet")
  If javaasp.WriteHeaders = True Then
  %>
  Headers were written <%
  Else
  %>
  Headers were not written <%
  End If
  Response.Write(galout)
  %>
  <H1> The End ...</H1>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章