Servlet規范描述了HTTP請求及響應處理過程相關的對象及其作用。本文就來介紹下Servlet規范中一些重要的接口。
Servlet接口
Servlet規范的核心接口即是Servlet接口,它是所有Servlet類必須實現的接口。在Java Servelt API中已經提供了兩個抽象類方便開發者實現Servlet類,分別是GenericServlet和HttpServlet, GenericServlet定義了一個通用的、協議無關的Servlet,而HttpServlet則定義了HTTP的Servlet,這兩個抽象類可以使Servlet類復用很多共性功能。
Servlet的生命周期主要包括加載實例化、初始化、處理客戶端請求、銷毀。加載實例化主要由Web容器完成,而其他三個階段則對應Servlet的init、service和destroy方法。
ServletRequest接口
ServletRequest接口的實現類封裝了客戶端請求的所有信息,如果使用HTTP協議通信則包括HTTP的請求行和請求頭部。HTTP對應的請求對象類型是HttpServletRequest類。ServletRequest接口的實現類中的信息包括以下幾部分。
-
一些HTTP請求頭部的獲取方法,如getHeader、getHeaders和getHeaderNames。
-
一些獲取請求路徑的方法,如getContextPath、getServletPath和getPathInfo,對於路徑變量,其中requestURI=contextPath+servletPath+pathInfo,而getRealPath方法則是獲取某個相對路徑對應的文件系統路徑。
-
獲取Cookie的方法,如getCookies方法;提供了判斷標識是否為HTTPS的方法,如isSecure方法。
-
獲取客戶端語言環境的方法,如getLocale和getLocales,它們對應HTTP的Accept-Language頭部
-
獲取客戶端編碼的方法,如getCharacterEncoding,對應HTTP協議的Content-Type頭部。
ServletRequest接口的對象只在Servlet的service方法或過濾器的doFilter方法作用域內有效,除非啟用了異步處理以調用ServletRequest接口對象的startAsync方法,此時request對象會一直有效,直到調用AsyncContext的complete方法。另外,Web容器通常會出於性能原因而不銷毀ServletRequest接口的對象,而是重復利用ServletRequest接口對象。
ServletContext接口
ServletContext接口定義了運行所有Servlet的Web應用的視圖。其提供的內容包括以下幾個部分。
-
某個Web應用的Servlet全局存儲空間,某Web應用對應的所有Servlet共有的各種資源和功能的訪問。
-
獲取Web應用的部署描述配置文件的方法,例如getInitParameter和getInitParameterNames。
-
添加Servlet到ServletContext里面的方法,例如addServlet。
-
添加Filter(過濾器)到ServletContext里面的方法,例如addFilter。
-
添加Listener(監聽器)到ServletContext里面的方法,例如addListener。
-
全局的屬性保存和獲取功能,例如setAttribute、getAttribute、getAttributeNames和removeAttribute等
-
訪問Web應用靜態內容的方法,例如getResource和getResourceAsStream,以路徑作為參數進行查詢,此參數要以“/”開頭,相對於Web應用上下文的根或相對於Web應用WEB-INF/lib目錄下jar包的META-INF/resources。
所有Servlet及它們使用的類需要由一個單獨的類加載器加載。每個實現ServletContext接口的對象都需要一個臨時存儲目錄,Servlet容器必須為每個ServletContext分配一個臨時目錄,並可在ServletContext接口中通過javax.servlet.context.tempdir屬性獲取該目錄。
ServletResponse接口
ServletResponse接口的對象封裝了服務器要返回客戶端的所有信息。如果使用HTTP,則包含了HTTP的響應行、響應頭部和響應體。
為了提高效率,一般ServletResponse接口對響應提供了輸出緩沖。其中,getBufferSize用於獲取緩沖區大小;setBufferSize用於設置緩沖區大小;flushBuffer強制刷新緩沖區;resetBuffer將清空緩沖區中的內容,但不清空請求頭部和狀態碼;isCommitted判斷是否有任何響應字節已經返回給客戶端;reset清空緩沖區內容,同時清空頭部信息和狀態碼。
ServletResponse接口對應HTTP的實現對象為HttpServletResponse,可以通過setHeader和addHeader方法向HttpServletResponse中添加頭部;可以通過sendRedirect將客戶端重定向到另外一個地址;可以通過sendError將錯誤信息輸出到客戶端。
當ServletResponse接口關閉時,緩沖區中的內容必須立即刷新到客戶端,ServletResponse接口只在Servlet的service方法或過濾器的doFilter方法的作用域內有效,除非它關聯的ServletResponse接口調用了startAsync方法啟用異步處理,此時ServletResponse接口會一直有效,直到調用AsyncContext的complete方法。另外,Web容器通常會出於性能原因而不銷毀ServletResponse接口對象,而是重復利用ServletResponse接口對象。
Filter接口
Filter接口允許Web容器對請求和響應做統一處理。例如,統一改變HTTP請求內容和響應內容,它可以作用於某個Servlet或一組Servlet。
Web應用部署完成后,必須實例化過濾器並調用其init方法。當請求進來時,獲取第一個過濾器並調用doFilter方法,接着傳入ServletRequest對象、ServletResponse對象及過濾器鏈(FilterChain), doFilter方法負責過濾器鏈中下一個實體的doFilter方法調用。當容器要移除某過濾器時必須先調用過濾器的destroy方法。
可以用“@WebFilter”注解或部署描述文件定義過濾器,XML配置形式使用
會話
Servlet沒有提出協議無關的會話規定,而是每個通信協議自己規定,HTTP對應的會話接口是HttpSession。Cookie是常用的會話跟蹤機制,其中Cookie的標准名字必須為JSESSIONID。另外一種會話跟蹤機制則是URL重寫,即在URL后面添加一個jsessionid參數,當支持Cookie和SSL會話的情況下,不應該使用URL重寫作為會話跟蹤機制。
會話ID通過調用HttpSession.getId()獲取,且能在創建后通過調用HttpServletRequest. changeSessionId()改變。HttpSession對象必須限定在ServletContext級別,會話里面的屬性不能在不同ServletContext之間共享。
Servlet可將某對象以鍵值對形式保存到HttpSession中,處於同一個ServletContext和相同會話中的任意Servlet都可以使用會話中保存的對象。如果某些對象想要在保存到會話或從會話中移除時得到通知,可以讓某個對象實現HttpSessionBindingListener接口,里面的valueBound和valueUnbound分別會在對應時刻觸發。
Servlet容器默認會話的超時時間,可以通過HttpSession的getMaxInactiveInterval方法獲取和setMaxInactiveInterval方法設置。
分布式環境中,會話的所有請求在同一時間必須僅被一個JVM處理,分布式容器遷移會話時會通知實現了HttpSessionActivationListener接口的所有會話屬性。
注解
Web應用中,使用了注解的類只有被放到WEB-INF/classes目錄中或WEB-INF/lib目錄下的jar中,注解才會被Web容器處理。web.xml配置文件的
@WebServlet注解用於在Web項目中定義Servlet,它必須指定urlPatterns或value屬性,默認的name屬性為完全限定類名,@WebServlet注解的類必須繼承javax.servlet.http.HttpServlet類。
@WebFilter注解用於在Web項目定義Filter,它必須指定urlPatterns、servletNames或value屬性,默認的filterName屬性為完全限定類名,使用@ WebFilter注解的類必須實現javax.servlet.Filter。
@WebInitParam注解用於指定傳遞到Servlet或Filter的初始化參數,它是WebServlet和WebFilter注解的一個屬性。
@WebListener注解用於定義Web應用的各種監聽器,使用@WebListener注解的類必須實現以下接口中的一個:
- javax.servlet.ServletContextListene
- javax.servlet.ServletContextAttributeListener
- javax.servlet.ServletRequestListener
- javax.servlet.ServletRequestAttributeListener
- javax.servlet.http.HttpSessionListener
- javax.servlet.http.HttpSessionAttributeListener
- javax.servlet.http.HttpSessionIdListener;
@MultipartConfig注解用於指定Servlet請求期望的是mime/multipart類型。
參考
本文摘錄自
- 《Tomcat內核設計剖析》