【tomcat】04 Servlet規範

一、介紹

百度百科

二、Servlet 接口

1、Servlet規範的核心接口即是Servlet接口,它是所有Servlet類必須實現的接口。

2、Java Servelt API中已經提供了兩個抽象類方便開發者實現Servlet類,分別是GenericServlet和HttpServlet。

  1. GenericServlet定義了一個通用的、協議無關的Servlet
  1. HttpServlet則定義了HTTP的Servlet
  1. 兩個抽象類可以使Servlet類複用很多共性功能

3、service方法:是處理客戶端請求的方法,客戶端發起的請求會被路由到對應的Servlet對象上。前面說到的

  1. HttpServlet類的service方法把對HTTP協議的GET、POST、PUT、DELETE、HEAD、OPTIONS、TRACE等請求轉發到各自的處理方法中,即doGet、doPost、doPut、doDelete、doHead、doOptions、doTrace等方法。HttpServlet提供了這些共性的處理邏輯,其他繼承它的類就不用再各自實現,只需要在對應的方法中做具體的處理邏輯即可。
  1. 例如我們做Web開發時常常會自己定義一個Servlet,並在doGet和doPost方法中做業務邏輯處理。

4、在Servlet容器中,每個Servlet類只能對應一個Servlet對象,所有請求都由同一個Servlet對象處理。

如果Servlet實現了SingleThreadModel接口則可能會在Web容器中存在多個Servlet對象。對於Web容器來說,實現了SingleThreadModel接口意味着一個Servlet對象對應着一個線程,所以此時Servlet的成員變量不存在線程安全問題。

5、Servlet的生命週期

graph LR
A(加載實例化)-->B(初始化)
B(初始化)-->C(處理客戶端請求)
C(處理客戶端請求)-->D(銷燬)
  1. 加載實例化主要由Web容器完成
  1. 其他三個階段則對應Servlet的init、service和destroy方法。

a) Servlet對象被創建後需要進行初始化操作,初始化工作可以放在以ServletConfig類型爲參數的ini方法中,ServletConfig爲web.xml配置文件中配置的對應的初始化參數,由Web容器完成web.xml配置讀取並封裝成ServletConfig對象。

b) Servlet初始化完成後,開始接受客戶端的請求,請求被封裝成ServletRequest類型的請求對象和ServletResponse類型的響應對象,通過service方法處理請求並響應客戶端。

c) 一個Servlet需要從Web容器中移除時,就會調用對應的destroy方法以釋放所有的資源,並且調用destroy方法之前要保證所有正在執行service方法的線程都完成執行。

三、ServletRequest接口

1、ServletRequest接口的實現類封裝了客戶端請求的所有信息。

如果使用HTTP協議通信則包括HTTP的請求行和請求頭部
HTTP對應的請求對象類型是HttpServletRequest類

2、ServletRequest接口的實現類中的信息

  1. 一些HTTP請求頭部的獲取方法,如getHeader、getHeaders和getHeaderNames。
  1. 一些獲取請求路徑的方法,如getContextPath、getServletPath和getPathInfo,對於路徑變量,其中requestURI=contextPath+servletPath+pathInfo,而getRealPath方法則是獲取某個相對路徑對應的文件系統路徑。
  1. 獲取Cookie的方法,如getCookies方法;提供了判斷標識是否爲HTTPS的方法,如isSecure方法。
  1. 獲取客戶端語言環境的方法,如getLocale和getLocales,它們對應HTTP的Accept-Language頭部。
  1. 獲取客戶端編碼的方法,如getCharacterEncoding,對應HTTP協議的Content-Type頭部

3、ServletRequest接口的對象只在Servlet的service方法或過濾器的doFilter方法作用域內有效。

  1. 啓用了異步處理以調用ServletRequest接口對象的startAsync方法,此時request對象會一直有效,直到調用AsyncContext的complete方法。
  1. Web容器通常會出於性能原因而不銷燬ServletRequest接口的對象,而是重複利用ServletRequest接口對象。

四、ServletContext接口

1、ServletContext接口定義了運行所有Servlet的Web應用的視圖

  1. Web應用的Servlet全局存儲空間,Web應用對應的所有Servlet共有的各種資源和功能的訪問。
  1. 獲取Web應用的部署描述配置文件的方法,如getInitParameter和getInitParameterNames。
  1. 添加Servlet到ServletContext裏面的方法,如addServlet。
  1. 添加Filter(過濾器)到ServletContext裏面的方法,如addFilter。
  1. 添加Listener(監聽器)到ServletContext裏面的方法,如addListener。
  1. 全局的屬性保存和獲取功能,如setAttribute、getAttribute、getAttributeNames和removeAttribute等。
  1. 訪問Web應用靜態內容的方法,如getResource和getResourceAsStream,以路徑作爲參數進行查詢,此參數要以“/”開頭,相對於Web應用上下文的根或相對於Web應用WEB-INF/lib目錄下jar包的META-INF/resources。

2、所有Servlet及它們使用的類需要由一個單獨的類加載器加載。

3、每個實現ServletContext接口的對象都需要一個臨時存儲目錄,Servlet容器必須爲每個ServletContext分配一個臨時目錄,並可在ServletContext接口中通過javax.servlet.context.tempdir屬性獲取該目錄。

五、ServletResponse接口

1、ServletResponse接口的對象封裝了服務器要返回客戶端的所有信息。

如果使用HTTP,則包含了HTTP的響應行、響應頭部和響應體。

2、爲了提高效率,一般ServletResponse接口對響應提供了輸出緩衝。

getBufferSize用於獲取緩衝區大小

setBufferSize用於設置緩衝區大小

flushBuffer強制刷新緩衝區

resetBuffer將清空緩衝區中的內容,但不清空請求頭部和狀態碼;

isCommitted判斷是否有任何響應字節已經返回給客戶端

reset清空緩衝區內容,同時清空頭部信息和狀態碼。

3、ServletResponse接口對應HTTP的實現對象爲HttpServletResponse,可以通過setHeader和addHeader方法向HttpServletResponse中添加頭部;可以通過sendRedirect將客戶端重定向到另外一個地址;可以通過sendError將錯誤信息輸出到客戶端。

4、ServletResponse接口關閉時,緩衝區中的內容必須立即刷新到客戶端,ServletResponse接口只在Servlet的service方法或過濾器的doFilter方法的作用域內有效,除非它關聯的ServletResponse接口調用了startAsync方法啓用異步處理,此時ServletResponse接口會一直有效,直到調用AsyncContext的complete方法。Web容器通常會出於性能原因而不銷燬ServletResponse接口對象,而是重複利用ServletResponse接口對象。

六、Filter接口

1、Filter接口允許Web容器對請求和響應做統一處理。

如:統一改變HTTP請求內容和響應內容,它可以作用於某個Servlet或一組Servlet。

2、Web應用部署完成後,必須實例化過濾器並調用其init方法。當請求進來時,獲取第一個過濾器並調用doFilter方法,接着傳入ServletRequest對象、ServletResponse對象及過濾器鏈(FilterChain),doFilter方法負責過濾器鏈中下一個實體的doFilter方法調用。當容器要移除某過濾器時必須先調用過濾器的destroy方法。

3、可以用“@WebFilter”註解或部署描述文件定義過濾器,XML配置形式使用元素定義,包括、和子節點,並使用定義Web應用的Servlet和其他靜態資源通過過濾器。

七、會話

1、Servlet沒有提出協議無關的會話規定,而是每個通信協議自己規定。

  1. HTTP對應的會話接口是HttpSession
  1. Cookie是常用的會話跟蹤機制,其中Cookie的標準名字必須爲JSESSIONID。
  1. 另外一種會話跟蹤機制則是URL重寫,即在URL後面添加一個jsessionid參數,當支持Cookie和SSL會話的情況下,不應該使用URL重寫作爲會話跟蹤機制。會話ID通過調用HttpSession.getId()獲取,且能在創建後通過調用HttpServletRequest.changeSessionId()改變。
  1. HttpSession對象必須限定在ServletContext級別,會話裏面的屬性不能在不同ServletContext之間共享。

2、Servlet可將某對象以鍵值對形式保存到HttpSession中,處於同一個ServletContext和相同會話中的任意Servlet都可以使用會話中保存的對象。

如果某些對象想要在保存到會話或從會話中移除時得到通知,可以讓某個對象實現HttpSessionBindingListener接口,裏面的valueBound和valueUnbound分別會在對應時刻觸發。

3、Servlet容器默認會話的超時時間,可以通過HttpSession的getMaxInactiveInterval方法獲取和setMaxInactiveInterval方法設置。

4、分佈式環境中,會話的所有請求在同一時間必須僅被一個JVM處理,分佈式容器遷移會話時會通知實現了HttpSessionActivationListener接口的所有會話屬性。

八、註解

1、Web應用中,使用了註解的類只有被放到WEB-INF/classes目錄中或WEB-INF/lib目錄下的jar中,註解纔會被Web容器處理。web.xml配置文件的元素的metadata-complete默認爲false,這表示Web容器必須檢查類的註解和Web Fragment,否則忽略註解和Web Fragment。

2、@WebServlet註解

用於在Web項目中定義Servlet,它必須指定urlPatternsvalue屬性,默認的name屬性爲完全限定類名,@WebServlet註解的類必須繼承javax.servlet.http.HttpServlet類。

3、@WebFilter註解

用於在Web項目定義Filter,它必須指定urlPatterns、servletNames或value屬性,默認的filterName屬性爲完全限定類名,使用@ WebFilter註解的類必須實現javax.servlet.Filter。

4、@WebInitParam註解

用於指定傳遞到Servlet或Filter的初始化參數,它是WebServlet和WebFilter註解的一個屬性。

5、@WebListener註解用於定義Web應用的各種監聽器 必須實現

javax.servlet.ServletContextListener

javax.servlet.ServletContextAttributeListener

javax.servlet.ServletRequestListener

javax.servlet.ServletRequestAttributeListener

javax.servlet.http.HttpSessionListener

javax.servlet.http.HttpSessionAttributeListener

javax.servlet.http.HttpSessionIdListener;

九、可插拔性

1、爲了給Web開發人員提供更好的可插拔性和更少的配置,可以在一個庫類或框架jar包的META-INF目錄中指定Web Fragment,即web-fragment.xml配置文件,它可以看成Web的邏輯分區,web-fragment.xml與web.xml包含的元素基本上都相同。

2、部署期間,Web容器會掃描WEB-INF/lib目錄下jar包的META-INF/web-fragment.xml文件,並根據配置文件生成對應的組件。

3、一個Web應用可能會有一個web.xml和若干個web-fragment.xml文件,Web容器加載時會涉及順序問題。有兩種方式定義它們加載的順序:絕對順序,web.xml中的元素用於描述加載資源的順序;相對順序,web-fragment.xml中的元素用於描述web-fragment.xml之間的順序。

十、請求分發器

1、負責把請求轉發給另外一個Servlet處理,或在響應中包含另外一個Servlet的輸出,RequestDispatcher接口提供了此實現機制。

2、用戶可以通過ServletContext的getRequestDispatcher方法和getNamedDispatcher方法分別以路徑或Servlet名稱作爲參數獲取對應Servlet的RequestDispatcher。

3、請求分發器有include和forward兩個方法。

  1. include方法是將目標Servlet包含到當前的Servlet中,主控制權在當前Servlet上。
  1. forward方法是將當前Servlet的請求轉移到目標Servlet上,主控權在目標Servlet上,當前Servlet的執行終止。

十一、Web應用

1、Web應用和ServletContext接口對象是一對一的關係,ServletContext對象提供了一個Servlet和它的應用程序視圖。

2、Web應用可能包括Servlet、JSP、工具類、靜態文件、客戶端Java Applet等。Web應用結構包括WEB-INF/web.xml文件、WEB-INF/lib/目錄下存放的所有jar包、WEB-INF/classes/目錄中存放的所有類、META-INF目錄存放的項目的一些信息,以及其他根據具體目錄存放的資源。

3、一般WEB-INF目錄下的文件都不能由容器直接提供給客戶端訪問,但WEB-INF目錄中的內容可以通過Servlet代碼調用ServletContext的getResource和getResourceAsStream方法來訪問,並可使用RequestDispatcher調用公開這些內容。

4、Web容器用於加載WAR文件中Servlet的類加載器必須提供getResource方法,以加載WAR文件的JAR包中包含的任何資源。

  1. 容器不允許Web應用程序覆蓋或訪問容器的實現類。
  1. 一個類加載器的實現必須保證部署到容器的每個Web應用,在調用Thread.currentThread.getContextClassLoader()時返回一個規定的ClassLoader實例。
  2. 部署的每個Web應用程序的ClassLoader實例必須是一個單獨的實例。

5、服務器應該能在不重啓Web容器的情況下更新一個Web應用程序,而更新Web應用程序時Web容器應該提供可靠的方法保存這些Web應用的會話。

如果調用response的sendError方法或如果Servlet產生一個異常或把錯誤傳播給容器,容器要按照Web應用部署描述文件中定義的錯誤頁面列表,根據狀態碼或異常試圖返回一個匹配的錯誤頁面。如果Web應用部署描述文件的error-page元素沒有包含exception-type或error-code子元素,則錯誤頁面使用默認的錯誤頁面。

6、Web應用的部署描述符中可以配置歡迎文件列表。當一個Web的請求URI沒有映射到一個Web資源時,可以從歡迎文件列表中按順序匹配適合的資源返回給客戶端,

如歡迎頁爲index.html,則http://localhost:8080/webapp請求實際變爲http://localhost:8080/webapp/index.html。如果找不到對應的歡迎頁,則返回404響應。

7、當一個Web應用程序部署到容器中時,在Web應用程序開始處理客戶端請求之前,先執行以下步驟

  1. 實例化部署描述文件中元素標識的每個事件監聽器的一個實例
  1. 已實例化且實現了ServletContextListener接口的監聽器實例,調用contextInitialized()方法。
  1. 實例化部署描述文件中元素標識的每個過濾器的一個實例,並調用每個過濾器實例的init()方法。
  1. 根據load-on-startup 元素值定義的順序,包含元素的元素爲每個Servlet實例化一個實例,並調用每個Servlet實例的init()方法。

十二、Servlet映射

1、對於請求的URL, Web容器根據最長的上下文路徑匹配請求URL,匹配Servlet。

2、Servlet的路徑是從整個請求URL中減去上下文和路徑參數。

3、匹配規則

  1. Web容器嘗試匹配一個精確的Servlet路徑,如果匹配成功,則選擇該Servlet。
  1. Web容器遞歸嘗試匹配最長的路徑前綴
  1. 如果URL最後包含擴展名

4、如.jsp, Web容器將試圖匹配一個專門用於處理此擴展名的Servlet。如果前三個規則都不匹配,則匹配一個默認的Servlet

十三、部署描述文件

所有Servlet容器的Web應用程序部署描述文件需要支持以下類型的配置和部署信息

Session配置

Servlet聲明

Servlet映射

應用程序生命週期監聽器類

過濾器定義和過濾器映射

MIME類型映射

歡迎文件列表

錯誤頁面

語言環境和編碼映射

安全配置(包括login-config、security-constraint、security-constraint、security-role-ref和run-as)

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