1. Servlet概述
Servlet是一個運行在服務器端的java小程序,通過Http協議用於接收客戶端的請求,併發出響應。Servlet是JavaWeb三大組件之一,也是最重要的組件!三大組件:Servlet、Filter、Listener。
2. Servlet入門
(1)編寫一個java類,實現servlet接口
(2)修改web.xml文件,給servlet提供一個可訪問的URI地址
(3)將應用部署到tomcat服務器
(4)測試:http://localhost:8080/Servlet/ss
3. Servlet執行過程
4. Servlet生命週期
實例化-->初始化-->服務-->銷燬
出生:(實例化-->初始化)第一次訪問Servlet就出生(默認情況下)
活着:(服務)應用活着,servlet就活着
死亡:(銷燬)應用卸載了servlet就銷燬。
Servlet接口中一共是5個方法,其中有三個是生命週期方法。
void init(ServletConfig):這個方法會在Servlet被創建後,馬上被調用。只會被調用一次!我們可以把一些初始化工作放到 這個方法中,如果沒有什麼初始化工作要做,那麼這個方法就空着就可以了。【Servlet有兩個時 間點會被創建:一是在第一次被請求時,會被創建;二是Tomcat啓動時被創建,默認是第一種, 如果希望在tomcat啓動時創建,這需要在web.xml中配置。】
void destroy():這個方法會在Servlet被銷燬之前被調用。如果你有一些需要釋放的資源,可以在這個方法中完成,如果沒有 那麼就讓這個方法空着。這個方法也只會被調用一次!【Servlet輕易不會被銷燬,通常會在Tomcat關閉時 會被銷燬。】
void service(ServletRequest,ServletResponse):它會在每次被請求時調用!這個方法會被調用0~N次。
String getServletInfo():它不是生命週期方法,也就是說它不會被tomcat調用。它可以由我們自己來調用,但我們一般也 不調用它!你可以返回一個對當前Servlet的說明性字符串。
Servlet ConfiggetServletConfig():這個方法返回的是ServletConfig,這個類型與init()方法的參數類型相同。它對應的是 web.xml中的配置信息,即<servlet>
4.1 Servlet映射路徑( url-pattern配置)
創建servlet後,如果想要這個servlet可以被訪問到,必須在web.xml文件中對其進行配置。在其中有一個<url-pattern>這個標籤是用於確定訪問servlet的路徑。一個servlet可以被不同的路徑映射,即多個不同配置可以映射同一個servlet.
對於<url-pattern>在開發中它的寫法有以下幾種:
完全匹配 要求必須以”/”開始
目錄匹配 必須以”/”開始,以”*”結束
擴展名匹配 不能以”/”開始,以*.xxx結束 xxx代表的是後綴名
優先級完全匹配>目錄匹配>擴展名匹配
注意:
1)url-pattern要麼以 / 開頭,要麼以*開頭。 例如ss是非法路徑。
2)不能同時使用兩種模糊匹配,例如 /ss/*.do是非法路徑
3)當有輸入的URL有多個servlet同時被匹配的情況下:
3.1 精確匹配優先。(長的最像優先被匹配)
3.2 以後綴名結尾的模糊url-pattern優先級最低!!!
4.2 Servlet缺省路徑
servlet的缺省路徑(<url-pattern>/</url-pattern>)是在tomcat服務器內置的一個路徑。該路徑對應的是一個DefaultServlet(缺省Servlet)。這個缺省的Servlet的作用是用於解析web應用的靜態資源文件。
根據URL讀取文件的的原理 :URL輸入http://localhost:8080/servlet001/index.html
1)到當前Servlet001應用下的web.xml文件查找是否有匹配的url-pattern。
2)如果沒有匹配的url-pattern,則交給tomcat的內置的DefaultServlet處理
3)DefaultServlet程序到day10應用的根目錄下查找是存在一個名稱爲index.html的靜態文件。
4)如果找到該文件,則讀取該文件內容,返回給瀏覽器。
5)如果找不到該文件,則返回404錯誤頁面。
總結:先找動態資源,再找靜態資源。
4.3 Servlet自動加載
Servlet默認是第一次訪問時候創建實例。通過配置,服務器啓動,創建實例。init做初始化的操作,非常消耗時間的。
在<servlet>標籤下配置
<load-on-startup>3</load-on-startup>
值是正整數,如果值越小,優先級越高。
5. Servlet的創建方式
(1)實現javax.servlet.Servlet接口
(2)繼承javax.servlet.GenericServlet類(適配器模式)
(3)繼承javax.servlet.http.HttpServlet類(模板方法設計模式)
Servlet -->GenericServlet-->HttpServlet-->(繼承HttpServlet)
6. Servlet的線程安全問題
Servlet是單例的,一個servlet對象可能同時處理多個請求。所以當多個servlet線程同時訪問servlet共享數據,如成員變量,可能會引發線程安全問題。解決辦法:
a.把使用到共享數據的代碼塊進行同步(使用synchronized關鍵字進行同步)
b.在servlet類中儘量不要使用成員變量。如果非要使用成員變量,必須同步。而且儘量縮小同步代碼塊的範圍。
7. Servlet接口
Servlet接口定義所有servlet 都必須實現的方法,包括初始化 servlet 的方法、爲請求提供服務的方法和從服務器移除 servlet 的方法。這些方法稱爲生命週期方法,它們是按以下順序調用的:
1.構造 servlet,然後使用 init 方法將其初始化。 2.處理來自客戶端的對 service 方法的所有調用。 3.從服務中取出 servlet,然後使用 destroy 方法銷燬它,最後進行垃圾回收並終止它。 |
除了生命週期方法之外,此接口還提供了getServletConfig 方法和 getServletInfo 方法,servlet 可使用前一種方法獲得任何啓動信息,而後一種方法允許 servlet 返回有關其自身的基本信息,比如作者、版本和版權。
8. GenericServletd類
GenericServlet是HttpServlet的父類,它也是一個抽象類,主要處理一般的,與協議無關的servlet,如果要編寫關於http協議使用HttpServlet。
GenericServlet實現了一個Servlet接口,這個接口定義了所有的servlet都必須實現的方法。它代理了ServletConfig的所有功能。所有使用ServletConfig才能調用的方法,都可以使用GenericServlet的同名方法來完成!不能覆蓋父類的init(ServltConfig)方法,因爲在父類中該方法內完成了this.config=config,其他的所有ServletConfig的代理方法都使用this.config來完成的。一旦覆蓋,那麼this.config就是null。如果需要做初始化工作,那麼可以去覆蓋GenericServlet提供的init()方法。
9. HttpServlet類
Javax.servlet.http.HttpServlet類,是一個抽象類,它的作用是提供將要被子類以創建適用於web 站點的Http servlet的抽象類。而對於HttpServlet的子類,一般需要重寫以下方法。
doGet,如果 servlet 支持 HTTP GET 請求 doPost,用於 HTTP POST 請求 init 和 destroy,用於管理 servlet 的生命週期內保存的資源 getServletInfo,servlet 使用它提供有關其自身的信息 |
在開發中一般重寫doPost、doGet方法。
10. ServletConfig對象
10.1 ServletConfig概述
ServletConfig是javax.servlet包下的一個接口,它是由servlet容器(tomcat)創建,並封裝了servlet相關配置信息的對象,並在servlet容器初始化期間傳遞給了servlet.,通過init(ServletConfigconfig)方法傳遞。
(1)作用
ServletConfig對象: 主要是用於加載servlet的初始化參數。在一個web應用可以存在多個ServletConfig對象 (一 個Servlet對應一個ServletConfig對象)
(2)對象的創建與獲取
創建時機: 在創建完servlet對象之後,在調用init方法之前創建。
得到對象: 直接從有參數的init方法中得到
(3)servlet初始化參數設置
在web.xml文件中我們可以對servlet進行配置,在<servlet>配置標籤內可以有以下這樣的子標籤
<init-param>
<param-name>參數名稱</param-name>
<param-value>參數值</param-value>
</init-param>
(4)有參數init(ServletConfig config)與無參數init()方法關係:
有參數的init方法,是servlet接口中定義的。
而無參數的init方法是GenericServlet中定義的。
在GenericServlet中重寫了有參數的init方法,並在其中調用了無參數的init方法。
那麼,在創建一個servlet時,如果是繼承了HttpServlet,在重寫init方法時,就可以只重寫無參數init就可以。
(5)ServletConfig主要作用有以下三個方面:
獲取Servlet名稱 getServletName()
獲取Servlet初始化參數 getInitParameter() getInitParameterNames()
獲取ServletContext對象
10.2 獲取ServletConfig對象
在servlet中如果想要獲取到ServletConfig對象,可以通過getServletConfig()對象來獲取。這個方法是在javax.servlet.Servlet接口中定義的,在GenericServlet中對getServletConfig()方法進行了實現。代碼如下:
ServletConfigconfig=this.getServletConfig();
10.3 ServletConfig常用方法
String getServletName()
獲取在web應用程序中部署的servlet實例的名稱(servletName中定義的)
String getInitParameter(Stringname)
獲取指定初始化參數的值,如果不存在,返回null
Enumeration getInitParameterNames()
以 String 對象的Enumeration 的形式返回 servlet 的初始化參數的名稱
ServletContext getServletContext()
返回對調用者在其中執行操作的ServletContext 的引用(獲取servlet的管理者)。
11. ServletContext
11.1 ServletContext概述
ServletContext它是javax.servlet.包下的一個接口。WEB容器在啓動時,它會爲每個WEB應用程序都創建一個對應的ServletContext對象,它代表當前web應用。ServletConfig對象中維護了ServletContext對象的引用,開發人員在編寫servlet時,可以通過ServletConfig.getServletContext方法獲得ServletContext對象。由於一個WEB應用中的所有Servlet共享同一個ServletContext對象,因此Servlet對象之間可以通過ServletContext對象來實現通訊。ServletContext對象通常也被稱之爲context域對象。
獲取 :context=this.getServletConfig().getServletContext();
在開發中可以通過以下方式獲取
ServletContextcontext=this.getServletContext();
在getServletContext()方法內部也是通過ServletContextServletConfig獲取的。
ServlectContext作用
獲取全局初始化參數
實現servlet共享資源
獲取web資源
其它操作
11.2 ServletContext獲取初始化參數
在web.xml文件中有<context-param>標籤可以設置全局初始化參數.
<context-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</context-param>
對於ServletContext對象它也提供了以下兩個方法用於獲取初始化參數
String getInitParameter(String name)
Enumeration getInitParameterNames()
11.3 ServletContext實現servlet共享
ServletContext對於一個web應用只有一個,所有的servlet使用的就是同一個ServletContext。
ServletContext提供以下方法用於在域中進行數據操作
Object getAttribute(String name)
返回具有給定名稱的servlet 容器屬性,如果不具有該名稱的屬性,則返回 null。
void setAttribute(String name,Object object)
將對象綁定到此servlet 上下文中的給定屬性名稱。如果已將指定名稱用於某個屬性,則此方法將使用新屬性替換具有該名稱的屬性。
void removeAttribute(String name)
從 servlet 上下文中移除具有給定名稱的屬性。
11.4 ServletContext獲取web中的資源
String getRealPath(String path)
爲給定虛擬路徑返回包含實際路徑的 String(返回的路徑到項目名稱)
InputStream getResourceAsStream(String path)
以 InputStream對象的形式返回位於指定路徑上的資源。
String getMimeType(String file) 可以獲取一個文件的mimeType類型.
URL getResource(String path) 它返回的是一個資源的URL
還提供log(String msg),getRequestDispatcher(String path) 等這樣的方法,可以做日誌與轉向操作
12. Classpath
java project----所有class都在bin目錄下
web project-----所有的class都在classes目錄下
12.1 Class獲取
Class.getResource("/").getPath();獲取classes目錄的絕對磁盤路徑
Class.getResource("").getPath();獲取的是當前Class對象代表的類所在的包的路徑。
12.2 ClassLoader獲取
Class.getClassLoader().getResource("/").getPath();
獲取的是classes目錄的絕對磁盤路徑
Class.getClassLoader().getResource("").getPath();
獲取的是classes目錄的絕對磁盤路徑
這兩個getResource()是使用當前ClassLoader加載資源(即資源在 Classpath中),這樣資源和class直接打在jar包中,避免文件路徑問題.兩者不同是Class的getResource()方法是從當前.class 文件路徑查找資源,ClassLoader則是從jar包根目錄查找.。
總結:
ServletRequest:封裝了請求信息;
ServletResposne:用於向客戶端響應;
ServletContext:它可以在多個Servlet中共享數據。
ServletConfig:它與<servlet>對應!
在<servlet>中可以配置<init-param>,即初始化參數,可以使用ServletConfig的getInitParameter(String),方法的參數是初始化參數名,方法的返回值是初始化參數值。
getInitParameterNames(),該方法返回一個Enumeration對象,即返回所有初始化參數的名稱。
String getServletName(),它返回的是<servlet-name>元素的值
ServletContext getServletContext(),它可以獲取Servlet上下文對象。