程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> Servlet動態網頁技術詳解

Servlet動態網頁技術詳解

編輯:關於JSP

一、Servlet簡介:
隨著互聯網技術的逐步普及,以及人們對互聯網要求提高,以前那種靜態網頁已經不再是適應,我們看到今天的網頁不但有flash,vide等等,顯然
以前的那種靜態網頁展示無法解決,為了解決這個問題,SUN公司提供了一門用於解決上述出現的問題的技術,這就是Servlet技術。
Servlet是sun公司提供的一門用於開發動態web資源的技術。
Sun公司在其API中提供了一個servlet接口,用戶若想用發一個動態web資源(即開發一個Java程序向浏覽器輸出數據),需要完成以下2個步驟:
編寫一個Java類,實現servlet接口。
把開發好的Java類部署到web服務器中。

二、Servlet的運行過程:
Servlet程序是由WEB服務器調用,web服務器收到客戶端的Servlet訪問請求後:
1.Web服務器首先檢查是否已經裝載並創建了該Servlet的實例對象。如果是,則直接執行第4步,否則,執行第2步。
2.裝載並創建該Servlet的一個實例對象。
3.調用Servlet實例對象的init()方法。
創建一個用於封裝HTTP請求消息的HttpServletRequest對象和一個代表HTTP響應消息的HttpServletResponse對象,然後調用Servlet的service()方法並將請求和響應對象作為參數傳遞進去。
4.WEB應用程序被停止或重新啟動之前,Servlet引擎(WEB服務器中調用該Servlet的類)將卸載Servlet,並在卸載之前調用Servlet的destroy()方法。

三、Servlet的生命周期:
1.說到生命周期,那麼我們就不得不提一下周期的概念,那麼什麼是生命周期的概念呢?
生命周期定義:一件事物,什麼時候生,什麼時候死,以及在其生存階段的某一時點會觸發的事件,統稱為該事物的生命周期。
Servlet的生命周期:
通常情況下,服務器會在Servlet第一次被調用時創建該Servlet類的實例對象(servlet出生);一旦被創建出來,該Servlet實例就會駐留在內存中,為後續請求服務;直至web容器退出,servlet實例對象才會被銷毀(servlet死亡)。
在Servlet的整個生命周期內,Servlet的init方法只有在servlet被創建時被調用一次。
而對一個Servlet的每次訪問請求都導致Servlet引擎調用一次servlet的service方法。對於每次訪問請求,Servlet引擎都會創建一個新的HttpServletRequest請求對象和一個新的HttpServletResponse響應對象,
然後將這兩個對象作為參數傳遞給它調用的Servlet的service()方法,service方法再根據請求方式分別調用doXXX方法。servlet被銷毀前,會調用destroy() 方法。

2.Servlet接口的實現類:
我們知道,如果我們要實現Servlet接口,就必須全部實現裡面的全部方法,然而裡面的所有的方法並不是我們想要的,那這個時候,我們實現這個方法又有什麼用呢?
所以為了解決這個問題,我們一般不會去實現該接口,而是會去繼承該類的實現類,這樣我們只要實現我們想要的方法就行;

2.1SUN公司提供了通常用的實現類:
Servlet接口SUN公司定義了兩個默認實現類,分別為:GenericServlet、HttpServlet。

HttpServlet指能夠處理HTTP請求的servlet,它在原有Servlet接口上添加了一些與HTTP協議處理方法,它比Servlet接口的功能更為強大。因此開發人員在編寫Servlet時,通常應繼承這個類,而避免直接去實現Servlet接口。

HttpServlet在實現Servlet接口時,覆寫了service方法,該方法體內的代碼會自動判斷用戶的請求方式,如為GET請求,則調用HttpServlet的doGet方法,如為Post請求,則調用doPost方法。因此,開發人員在編寫Servlet時,
通常只需要覆寫doGet或doPost方法,而不要去覆寫service方法。

由於客戶端是通過URL地址訪問web服務器中的資源,所以Servlet程序若想被外界訪問,必須把servlet程序映射到一個URL地址上,這個工作在web.xml文件中使用<servlet>元素和<servlet-mapping>元素完成。
<servlet>元素用於注冊Servlet,它包含有兩個主要的子元素:<servlet-name>和<servlet-class>,分別用於設置Servlet的注冊名稱和Servlet的完整類名。
一個<servlet-mapping>元素用於映射一個已注冊的Servlet的一個對外訪問路徑,它包含有兩個子元素:<servlet-name>和<url-pattern>,分別用於指定Servlet的注冊名稱和Servlet的對外訪問路徑。例如:

復制代碼 代碼如下:
  <servlet>
     <servlet-name>servlet3</servlet-name>
     <servlet-class>cn.baidu.serlvet.Demo3Servlet</servlet-class>
   </servlet>
  <servlet-mapping>
  <servlet-name>servlet3</servlet-name>
  <url-pattern>/demo3</url-pattern>
  </servlet-mapping>

2.2Servlet中的一些小細節:
細節1:
同一個Servlet可以被映射到多個URL上,即多個<servlet-mapping>元素的<servlet-name>子元素的設置值可以是同一個Servlet的注冊名。
在Servlet映射到的URL中也可以使用*通配符,但是只能有兩種固定的格式:一種格式是“*.擴展名”,另一種格式是以正斜槓(/)開頭並以“/*”結尾。

復制代碼 代碼如下:
<servlet-mapping>
  <servlet-name>
  AnyName
  </servlet-name>
  <url-pattern>
  *.do
  </url-pattern>
</servlet-mapping>
<servlet-mapping>
  <servlet-name>
  AnyName
  </servlet-name>
  <url-pattern>
  /action/*
  </url-pattern>
</servlet-mapping>

細節2:
對於如下的一些映射關系:
Servlet1 映射到 /abc/*
Servlet2 映射到 /*
Servlet3 映射到 /abc
Servlet4 映射到 *.do
問題:
當請求URL為“/abc/a.html”,“/abc/*”和“/*”都匹配,哪個servlet響應
Servlet引擎將調用Servlet1。
當請求URL為“/abc”時,“/abc/*”和“/abc”都匹配,哪個servlet響應
Servlet引擎將調用Servlet3。
當請求URL為“/abc/a.do”時,“/abc/*”和“*.do”都匹配,哪個servlet響應
Servlet引擎將調用Servlet1。
當請求URL為“/a.do”時,“/*”和“*.do”都匹配,哪個servlet響應
Servlet引擎將調用Servlet2。
當請求URL為“/xxx/yyy/a.do”時,“/*”和“*.do”都匹配,哪個servlet響應
Servlet引擎將調用Servlet2。
細節3:
如果在<servlet>元素中配置了一個<load-on-startup>元素,那麼WEB應用程序在啟動時,就會裝載並創建Servlet的實例對象、以及調用Servlet實例對象的init()方法。
舉例:
復制代碼 代碼如下:
<servlet>
<servlet-name>invoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>

用途:為web應用寫一個InitServlet,這個servlet配置為啟動時裝載,為整個web應用創建必要的數據庫表和數據。

細節4:線程安全問題
當多個客戶端並發訪問同一個Servlet時,web服務器會為每一個客戶端的訪問請求創建一個線程,並在這個線程上調用Servlet的service方法,因此service方法內如果訪問了同一個資源的話,就有可能引發線程安全問題。
如果某個Servlet實現了SingleThreadModel接口,那麼Servlet引擎將以單線程模式來調用其service方法。
SingleThreadModel接口中沒有定義任何方法,只要在Servlet類的定義中增加實現SingleThreadModel接口的聲明即可。
對於實現了SingleThreadModel接口的Servlet,Servlet引擎仍然支持對該Servlet的多線程並發訪問,其采用的方式是產生多個Servlet實例對象,並發的每個線程分別調用一個獨立的Servlet實例對象。
實現SingleThreadModel接口並不能真正解決Servlet的線程安全問題,因為Servlet引擎會創建多個Servlet實例對象,而真正意義上解決多線程安全問題是指一個Servlet實例對象被多個線程同時調用的問題。
事實上,在Servlet API 2.4中,已經將SingleThreadModel標記為Deprecated(過時的)。

四、Servlet中常用的對象:
1.ServletConfig對象
1.1在Servlet的配置文件中,可以使用一個或多個<init-param>標簽為servlet配置一些初始化參數。
1.2當servlet配置了初始化參數後,web容器在創建servlet實例對象時,會自動將這些初始化參數封裝到ServletConfig對象中,
並在調用servlet的init方法時,將ServletConfig對象傳遞給servlet。進而,程序員通過ServletConfig對象就可以得到當前servlet
的初始化參數信息。
2.ServletContext對象
2.1WEB容器在啟動時,它會為每個WEB應用程序都創建一個對應的ServletContext對象,它代表當前web應用。
2.2ServletConfig對象中維護了ServletContext對象的引用,開發人員在編寫servlet時,可以通過ServletConfig.getServletContext方法獲得ServletContext對象。
2.3由於一個WEB應用中的所有Servlet共享同一個ServletContext對象,因此Servlet對象之間可以通過ServletContext對象來實現通訊。
ServletContext對象通常也被稱之為context域對象。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved