在 Servlet 3.0 中,要為 Web 應用程式進行 Servlet、過濾器、傾聽器的組態設定有幾種方式:
- 透過
@WebServlet
、@WebFilter
、@WebListener
等標註的設定。 - 透過 web.xml 的設定,如果 web.xml 中設定的 Servlet、過濾器等類別中已包括標註,則以 web.xml 中的設定為主。
- 在容器初始化時,透過
ServletContext
的addServlet()
、addFilter()
、addListener()
等方法來設定,這可以實作在ServletContextListener
的contextInitialized()
中,或者是ServletContainerInitializer
的onStartup()
中實作。
第三種方式以 Servlet 為例,ServletContext
上所新增的相關方法有:
ServletRegistration.Dynamic addServlet(java.lang.String servletName, java.lang.Class<? extends Servlet> servletClass)
ServletRegistration.Dynamic addServlet(java.lang.String servletName, Servlet servlet)
ServletRegistration.Dynamic addServlet(java.lang.String servletName, java.lang.String className)
<T extends Servlet> T createServlet(java.lang.Class<T> clazz) throws ServletException
ServletRegistration getServletRegistration(java.lang.String servletName)
java.util.Map<java.lang.String,? extends ServletRegistration> getServletRegistrations()
ServletRegistration
有 getMappings()
與 addMapping()
可以取得或增加 Servlet 的對應(Mapping)訊息,也就是相當於 web.xml 中 <servlet-mapping>
的資訊。
在一個 JAR 檔案中如果有個 META-INF/services/javax.servlet.ServletContainerInitializer 檔案,該檔案是個文件檔案,當中所撰寫的類別名稱若實作了 ServletContainerInitializer
介面,則在容器啟動時,將會載入這些類別並執行其 onStartup()
方法:
..
@HandlesTypes({OOO.class, XXX.class})
void onStartup(java.util.Set<java.lang.Class<?>> c, ServletContext ctx)
throws ServletException {
...
}
...
其中 @HandlesTypes
中指定的類別,將傳入給 onStartup()
的第一個參數,以便在 onStartup()
中處理。
如果要決定 Servlet、過濾器、傾聽器的載入順序,則一定要在 web.xml 中設定,載入的順序就是其在 web.xml 中宣告的順序(Servlet 的話,就是 load-on-startup
值一樣時的情況)。
實際上,在 Servlet 3.0 中支援對 Servlet、過濾器、傾聽器抽換性(pluggability),可以藉由在 JAR 中包括符合要求的文件,就可以達到置換 JAR 檔案即抽換 Servlet、過濾器、傾聽器的目的,這之後會再說明。