- 輕量級Java EE企業應用開發實戰
- 柳偉衛編著
- 2180字
- 2022-07-29 14:31:20
3.5 Servlet上下文
Servlet上下文定義了Servlet運行在Web應用的視圖,定義在ServletContext接口中。容器供應商負責提供Servlet容器的ServletContext接口的實現。Servlet可以使用ServletContext對象記錄事件,獲取URL引用的資源,存取當前上下文的其他Servlet可以訪問的屬性。
ServletContext是Web服務器中已知路徑的根。例如,Servlet上下文可以從https://waylau.com/catalog找出,“/catalog”請求路徑稱為上下文路徑,所有以它開頭的請求都會被路由到與ServletContext相關聯的Web應用。
3.5.1 ServletContext接口作用域
每一個部署到容器的Web應用都有一個ServletContext接口的實例與之關聯。在容器分布在多臺虛擬機的情況下,每個JVM的每個Web應用將有一個ServletContext實例。
如果容器內的Servlet沒有部署到Web應用中,就隱含地作為“默認”Web應用的一部分,并有一個默認的ServletContext。在分布式的容器中,默認的ServletContext是非分布式的且僅存在于一個JVM中。
3.5.2 初始化參數
以下ServletContext接口方法允許Servlet訪問由應用開發人員在Web應用的部署描述符中指定的上下文初始化參數:
- getInitParameter
- getInitParameterNames
應用開發人員使用初始化參數來表達配置信息。代表性的例子是一個網絡管理員的E-Mail地址,或保存關鍵數據的系統名稱。
3.5.3 配置方法
下面的方法從Servlet 3.0開始添加到ServletContext,以便啟用編程方式定義Servlet、Filter和它們映射到的URL模式。這些方法只能從ServletContextListener實現的contexInitialized方法或者ServletContainerInitializer實現的onStartup方法進行的應用初始化過程中調用。除了添加Servlet和Filter外,也可以查找關聯到Servlet或Filter的一個Registration對象實例,或者到Servlet或Filter的所有Registration對象的Map。
如果ServletContext傳到了ServletContextListener的contextInitialized方法,但該ServletContextListener既沒有在web.xml或web-fragment.xml中聲明,又沒有使用@WebListener注解,那么在ServletContext中定義的用于Servlet、Filter和Listener的編程式配置的所有方法必須拋出nsupportedOperationException。
1.編程式添加和配置Servlet
編程式添加Servlet到上下文對框架開發者是很有用的。例如,框架可以使用這個方法聲明一個控制器Servlet。這個方法將返回一個ServletRegistration或ServletRegistration.Dynamic對象,允許我們進一步配置如init-params、url-mapping等Servlet的其他參數。
下面描述常用的添加和配置Servlet的方法。
- addServlet(String servletName, String className):該方法允許應用以編程方式聲明一個Servlet。它添加給定的Servlet名稱和類名稱到Servlet上下文。
- addServlet(String servletName, Servlet servlet):該方法允許應用以編程方式聲明一個Servlet。它添加給定的名稱和Servlet實例的Servlet到Servlet上下文。
- addServlet(String servletName, Class <? extends Servlet> servletClass):該方法允許應用以編程方式聲明一個Servlet。它添加給定的名稱和Servlet類的一個實例的Servlet到Servlet上下文。
- T createServlet(Class clazz):該方法實例化一個給定的Servlet類,該方法必須支持適用于Servlet的除了@WebServlet的所有注解。返回的Servlet實例通過調用上面定義的addServlet(String, Servlet)注冊到ServletContext之前,可以進行進一步的定制。
- ServletRegistration getServletRegistration(String servletName):該方法返回與指定名字的Servlet相關的ServletRegistration,或者如果沒有該名字的ServletRegistration,就返回null。如果ServletContext傳到了ServletContextListener的contextInitialized方法,但該ServletContextListener既沒有在web.xml或web-fragment.xml中聲明,又沒有使用javax.servlet. annotation.WebListener注解,就必須拋出UnsupportedOperationException。
- Map getServletRegistrations():該方法返回ServletRegistration對象的Map,由名稱作為鍵并對應著注冊到ServletContext的所有Servlet。如果沒有Servlet注冊到ServletContext,就返回一個空的Map。返回的Map包括所有聲明和注解的Servlet對應的ServletRegistration對象,也包括那些使用addServlet方法添加的所有Servlet對應的ServletRegistration對象。返回的Map的任何改變都不影響ServletContext。如果ServletContext傳到了ServletContextListener的contextInitialized方法,但該ServletContextListener既沒有在web.xml或web-fragment.xml中聲明,又沒有使用javax.servlet.annotation.WebListener注解,就必須拋出UnsupportedOperationException。
2.編程式添加和配置Filter
- addFilter(String filterName, String className):該方法允許應用以編程方式聲明一個Filter。它添加以給定的Filter名稱和類名稱的Filter到Web應用。
- addFilter(String filterName, Filter filter):該方法允許應用以編程方式聲明一個Filter。它添加以給定的Filter名稱和Filter實例到Web應用。
- addFilter(String filterName, Class <? extends Filter> filterClass):該方法允許應用以編程方式聲明一個Filter。它添加以給定的Filter名稱和Filter類到Web應用。
- T createFilter(Class clazz):該方法實例化一個給定的Filter。
- FilterRegistration getFilterRegistration(String filterName):該方法返回與指定名字的Filter相關的FilterRegistration,或者如果沒有該名字的FilterRegistration,就返回null。如果ServletContext傳到了ServletContextListener的contextInitialized方法,但該ServletContextListener既沒有在web.xml或web-fragment.xml中聲明,又沒有使用javax.servlet.annotation.WebListener注解,就必須拋出UnsupportedOperationException。
- Map getFilterRegistrations():該方法返回FilterRegistration對象的Map,由名稱作為鍵并對應著注冊到ServletContext的所有Filter。如果沒有Filter注冊到ServletContext,就返回一個空的Map。返回的Map包括所有聲明和注解的Filter對應的FilterRegistration對象,也包括那些使用addFilter方法添加的所有Servlet對應的ServletRegistration對象。返回的Map的任何改變都不影響ServletContext。如果ServletContext傳到了ServletContextListener的contextInitialized方法,但該ServletContextListener既沒有在web.xml或web-fragment.xml中聲明,又沒有使用javax.servlet.annotation.WebListener注解,就必須拋出UnsupportedOperationException。
3.編程式添加和配置Listener
- void addListener(String className):往ServletContext添加指定類名的監聽器。ServletContext將使用由與應用關聯的classloader加載該監聽器的類。監聽器必須實現一個或多個如下接口:
javax.servlet.ServletContextAttributeListener
javax.servlet.ServletRequestListener
javax.servlet.ServletRequestAttributeListener
javax.servlet.http.HttpSessionListener
javax.servlet.http.HttpSessionAttributeListener
javax.servlet.http.HttpSessionIdListener
- void addListener(T t):往ServletContext添加一個給定的監聽器。給定的監聽器實例必須實現一個或多個如下接口:
javax.servlet.ServletContextAttributeListener
javax.servlet.ServletRequestListener
javax.servlet.ServletRequestAttributeListener
javax.servlet.http.HttpSessionListener
javax.servlet.http.HttpSessionAttributeListener
javax.servlet.http.HttpSessionIdListener
- void addListener(Class <? extends EventListener> listenerClass):往ServletContext添加指定類名的監聽器。給定的監聽器類必須實現一個或多個如下接口:
javax.servlet.ServletContextAttributeListener
javax.servlet.ServletRequestListener
javax.servlet.ServletRequestAttributeListener
javax.servlet.http.HttpSessionListener
javax.servlet.http.HttpSessionAttributeListener
javax.servlet.http.HttpSessionIdListener
- void createListener(Class clazz):該方法實例化給定的EventListener類。指定的EventListener類必須實現至少一個如下接口:
javax.servlet.ServletContextAttributeListener
javax.servlet.ServletRequestListener
javax.servlet.ServletRequestAttributeListener
javax.servlet.http.HttpSessionListener
javax.servlet.http.HttpSessionAttributeListener
javax.servlet.http.HttpSessionIdListener
3.5.4 上下文屬性
Servlet可以通過名字將對象屬性綁定到上下文。同一個Web應用內的其他任何Servlet都可以使用綁定到上下文的任意屬性。以下ServletContext接口中的方法允許訪問此功能:
- setAttribute
- getAttribute
- getAttributeNames
- removeAttribute
在JVM中創建的上下文屬性是本地的,這可以防止從一個分布式容器的共享內存存儲中獲取ServletContext屬性。當需要在運行在分布式環境的Servlet之間共享信息時,該信息應該被放到會話中,或存儲到數據庫,或設置到Enterprise JavaBeans(企業級JavaBean)組件。
3.5.5 資源
ServletContext接口提供了直接訪問Web應用中僅是靜態內容層次結構的文件的方法,包括HTML、GIF和JPEG文件等:
- getResource
- getResourceAsStream
getResource和getResourceAsStream方法需要一個以“/”開頭的String作為參數,給定的資源路徑是相對于上下文的根,或者相對于Web應用的WEB-INF/lib目錄下的JAR文件中的META-INF/resources目錄。這兩個方法首先根據請求的資源查找Web應用上下文的根,然后查找所有WEB-INF/lib目錄下的JAR文件。查找WEB-INF/lib目錄下JAR文件的順序是不確定的。這種層次結構的文件可以存在于服務器的文件系統、Web應用的歸檔文件、遠程服務器或其他位置。
需要注意的是,這兩個方法不能用于獲取動態內容。例如,在支持JSP的容器中,如getResource("/index.jsp")形式的方法調用將返回JSP源碼而不是處理后的輸出。
- 算法大爆炸:面試通關步步為營
- C語言程序設計
- Building Mapping Applications with QGIS
- 老“碼”識途
- Python機器學習實戰
- PHP+MySQL+Dreamweaver動態網站開發實例教程
- Oracle從入門到精通(第5版)
- Getting Started with NativeScript
- Webpack實戰:入門、進階與調優
- 蘋果的產品設計之道:創建優秀產品、服務和用戶體驗的七個原則
- Statistical Application Development with R and Python(Second Edition)
- Fastdata Processing with Spark
- Unity 5.X從入門到精通
- PHP+MySQL動態網站開發從入門到精通(視頻教學版)
- Arduino電子設計實戰指南:零基礎篇