淺析Servlet 3.0 API的概念
如今,像 Struts、JSF 和 Springweb 這樣的 web 框架已經被普遍接受,并已經確立成為構建 web 應用程序的技術。將這些框架集成為一個 web 應用程序并不是那么容易,因為這一過程涉及將不同的片段同化在一起,之后編輯一個描述如何將所有這些片段配合在一起的單獨描述符文件。絕大多數框架強制您在應用程序的部署描述符文件中配置像 servlet 類(通常為 控制器 Servlet)、過濾器類或者偵聽器類這樣的框架細節。這種必備配置的主要原因是當今的 web 應用程序只支持一個單獨的整體部署描述符,其中定義了所有的部署信息。當應用程序的大小增加時,外部框架的依賴關系可能也增加,從而生成復雜的部署描述符文件。正如您可能知道的,復雜描述的維護始終存在爭議。
為了解決這些問題,Servlet 3.0 API 最為顯著的概念之一是 web 片段 或者 模塊 web.xml 的思想。Web 片段是將 web 應用程序邏輯分區為 servlet、servlet-mapping、servlet-filter、filter-mapping、servlet-listener 之類的元素及其子元素。框架開發人員可以利用該功能以定義存在于框架內自己的 web 片段,開發人員可以在不修改現有的部署描述符的情況下僅僅通過將庫文件包含到應用程序的類路徑中來插入越來越多的框架。簡言之,該功能旨在當用框架或者庫進行工作時進行零配置。
對該部署描述符已經進行了更改以包含保存 web 片段細節的 這一新元素。如果該片段被打包為一個 .jar 文件且以部署描述符的形式具備元數據信息,則 web.xml 文件必須包含在 .jar 文件的 META-INF 目錄下。在部署時,器掃描應用程序的類路徑,查找所有 web 片段并加以處理。前面討論過的 metadata-complete 標志在應用程序啟動期間控制 web 片段的掃描。以下顯示了一個示例 web 片段:
- <web-fragment>
- <servlet>
- <servlet-name>myservlet</servlet-name>
- <servlet-class>samples.MyServlet</servlet-class>
- </servlet>
- <listener>
- <listener-class>samples.MyListener</listener-class>
- </listener>
- </web-fragment>
為了提供增強的可插拔性,Servlet 3.0 借助添加到 ServletContext 的 API 為增加 servlets 和過濾器類的編程提供了非常需要的支持。這些新的 API 使您能通過編程來聲明 servlets、過濾器類及其 URL 映射。這些類在應用程序啟動或者運行期間進行初始化。最重要的是,您只能通過 ServletContext 的 contextInitialized 方調用這些 API。有關這些 API 的更多信息,請參閱 Servlet 3.0 API 文檔。通過編程添加 servlet 和過濾器類的代碼示例如下所示:
- @ServletContextListener
- public class MyListener {
- public void contextInitialized (ServletContextEvent sce) {
- ServletContext sc = sce.getServletContext();
- //Declare servlet and servlet mapping
- sc.addServlet("myServlet", "Sample servlet", "samples.MyServlet", null, -1);
- sc.addServletMapping("myServlet", new String[] {"/urlpattern/*"});
- //Declare filter and filter mapping
- sc.addFilter("myFilter", "Sample Filter", " samples.MyFilter", null);
- sc.addFilterMapping("myFilter", new String[] {"/urlpattern/*"}, "myServlet",
- DispatcherType.REQUEST, false);
- }
- }
大家應該都遇到過 servlets 運行緩慢的問題,特別是 servlets 必須等待來自 web 服務、JDBC 連接、JMS 消息等的響應。在當前情況下,servlet 在生成響應前需要等待進程完成,這會導致低效率阻塞操作消耗容器的線程或者其他有限的資源。在采用 JDBC 連接時的另一個不利影響是,數據庫可能存在許多等待訪問的阻塞線程。這種情況最終將導致整個 web 容器的線程不足和服務質量下降。
為了克服上述缺點,Servlet 3.0 添加了對掛起和恢復請求處理的支持,使 servlet 以異步、非阻塞的方式響應請求(這就是編程的 Comet 樣式)。當一項請求被掛起時,處理請求的線程將在不生成任何響應的情況下返回給容器并準備執行其他任務。處理請求的 resume 方法恢復請求處理。只要當所請求的資源可用時,處理事件的線程才恢復被掛起的請并進行處理以生成響應。以下列舉的是異步 servlets 的一些功能:
即使數據到達緩慢(非阻塞輸入),也能在沒有阻塞事件的情況下從客戶機接收數據。
即使客戶機或者網絡運行緩慢(非阻塞輸出),也能在不發生阻塞的情況下向客戶機發送數據。
能處理被延遲的請求。如果在響應請求前必須獲得遠程/緩慢的資源,或者如果需要抑制訪問特定的資源以防止過多的同步訪問,對被延遲事件的處理是非常有用的。
能處理被延遲的響應關閉;也就是響應將保持打開以允許在發生異步事件時發送其他數據。
能通知阻塞或者非阻塞事件。
將新的 API 添加到 ServletRequest 和 ServletResponse,用于掛起、恢復和查詢請求的狀況、啟用禁用和查詢響應的狀況。開發人員可以分別通過 requestSuspended(), requestResumed() 和 requestCompleted() 方法使用請求的 resume、suspend 和 complete 方法通知事件。有關這些方法的詳細信息請參閱 Servlet 3.0 API。
【編輯推薦】