第十章 Web Application(JavaTM Servlet 規範3.1 )

Web 應用

Web應用是Web服務器上組成一個完整應用的 servlets,HTML pages,classes 和其餘資源的一個集合。Web應用能夠被捆綁並運行在不一樣供應商的不一樣容器內。html

10.1 Web服務器中的Web應用
java

Web服務器裏的Web應用以一個特定的路徑爲根。例如,catalog應用可能定位到http://www.mycorp.com/catalog。全部以此前綴爲開始的請求會被路由到表明該 catalog 應用的 ServletContext。servlet 容器能夠建立 Web應用的自動生成規則。例如 ~user/ 映射能夠用來映射一個基於/home/user/public_html的 Web應用。默認狀況下,在任何同一時間一個Web應用的實例必須運行在一個VM上。若是應用經過其部署描述符將其標記爲「distributable(分佈的)」,此行爲能夠被覆蓋。標記爲分佈的應用必須遵照比普通Web應用更嚴格的規則。本規範中設置了這些規則。web

10.2 與ServletContext的關係安全

servelt容器必須強制Web應用與 ServletContext 之間一一對應的。ServletContext 對象提供給 servlet 它的應用視圖。服務器

10.3 Web應用的元素session

Web應用能夠由如下項目組成:app

▪ Servlets 
webapp

▪JSP Pages1 
異步

▪工具類 
jsp

▪靜態文檔(HTML,圖片,聲音,等等)


▪客戶端Java applets,beans,和類 


▪將以上元素綁在一塊兒的描述性元信息

10.4  部署層次 


爲部署和打包目的,本規範定義了一個能夠存在於開放文件系統,歸檔文件或其它格式的層次結構。建議 servlet 容器支持該結構做爲運行時表現形式,但不是必須的。

10.5  目錄結構

Web 應用做爲一個結構化層級目錄存在。此結構層級的根做爲應用中文件的文檔根。例如,Web容器中以 /catalog 做爲上下文路徑的應用,Web應用層級根目錄下的 index.html 和 在WEB-INF/lib 下的JAR文件中/META-INF/resources 目錄下包含的index.html 都知足來自 /catalog/index.html 的請求。若是 index.html 同時存在於根上下文和 應用 WEB-INF/lib 目錄裏的JAR文件 /META-INF/resources中,則必須使用根上下文中的index.html。匹配 URLs 到上下文路徑的規則在12章」映射請求到Servlets」 中給出。因爲應用的上下文路徑決定了Web應用內容的 URL 命名空間,Web容器必須拒絕Web應用在此 URL 命名空間中定義可能形成潛在衝突的上下文路徑。好比嘗試部署相同上下文路徑的另一個Web應用,就會發生衝突。因爲請求匹配資源使用大小寫敏感的方式,潛在衝突的肯定也必須以大小寫敏感的方式進行。

在應用層級結構中存在一個名爲」WEB-INF」的特殊目錄。此目錄包含與應用相關的不在應用根文檔中的全部東西。大部分 WEB-INF 節點不是應用公共文檔樹的一部分。除了打包在位於 WEB-INF/lib 中的 JAR 文件中 META-INF/resources 的靜態資源和JSP,包含在 WEB-INF 目錄中的其餘文件不能被容器提供給客戶端。可是 WEB-INF 目錄的內容對調用 ServletContext 的 getResource 和 getResourceAsStream 方法的 servlet 代碼是可見的,而且可使用 RequestDispatcher 調用被公開。所以,若是應用開發者須要從 servlet 代碼訪問他不想直接對Web客戶端直接公開的應用特殊配置信息,能夠將它放到該目錄下。因爲請求匹配資源映射使用大小寫敏感的方式,例如客戶端請求,‘/WEB-INF/foo’, ‘/WEb-iNf/foo’,不該該將位於 /WEB-INF 下的Web應用的內容返回,包括任何形式的目錄列表。

WEB-INF 目錄的內容:

▪   /WEB-INF/web.xml 部署描述符。 


▪   /WEB-INF/classes/ servlet和工具類的目錄。此目錄中的類必須對應用的類加載器可用。


▪   /WEB-INF/lib/*.jar Java 歸檔文件區。這些文件包括打包在JAR文件中的 servlets,benas,靜態資源和JSPs 和其餘對Web應用有用的工具類。Web應用類加載器必須能從任何這些歸檔文件中加載類。Web 應用必須首先從 WEB-INF/classes 目錄加載類,而後從 WEB-INF/lib 目錄下的庫 JARs加載。另外,任何來自客戶端訪問 WEB-INF/ 目錄裏資源的請求,除了靜態資源被打包進JAR文件的狀況外,必須返回一個SC_NOT_FOUND(404)響應。


10.5.1 應用目錄結構示例

下面是一個示例Web應用中的全部文件列表:

/index.html

/howto.jsp

/feedback.jsp

/images/banner.gif

/images/jumping.gif

/WEB-INF/web.xml

/WEB-INF/lib/jspbean.jar

/WEB-INF/lib/catalog.jar!/META-INF/resources/catalog/moreOffers/books.html

/WEB-INF/classes/com/mycorp/servlets/MyServlet.class

/WEB-INF/classes/com/mycorp/util/MyUtils.class

10.6 Web 應用歸檔文件

使用標準Java歸檔工具,Web應用能夠被打包並簽入一個Web歸檔格式(WAR)文件。例如,一個用來「issue tracking(跟蹤問題)」的應用能夠發佈在一個名爲 issuetrack.war 的歸檔文件中。

當打包成這種格式時,將生成一個包含對Java歸檔工具備用信息的 META-INF 目錄。此目錄不能被容器做爲內容直接提供給做爲Web客戶端請求的響應,雖然它的內容對經過調用 ServletContext 的 getResource 和 getResourceAsStream 的 servlet 代碼是可見的。另外對任何訪問 META-INF 目錄下資源的請求必須返回 SC_NOT_FOUND(404) 響應。

10.7 Web 應用部署描述符

Web應用描述符(見14章:部署描述符)包括如下配置類型和部署信息:

▪   ServletContext 初始化參數 


▪   Session 配置 


▪   Servlet/JSP 定義 


▪   Servlet/JSP 映射 


▪   MIME Type 映射 


▪   Welcome File 列表 


▪  Error Pages

▪   Security 安全


10.7.1  擴展依賴 


當大量應用使用相同的代碼或資源時,他們一般會被做爲庫文件安裝進容器裏。這些文件常常是通用和標準的API,能夠在不犧牲移植性的狀況下使用。僅被一個或少數應用使用的文件將做爲Web應用的一部分來訪問。容器必須爲這些庫提供一個目錄。存放在這個目錄的文件必須能夠跨Web應用可用。這個目錄的位置是容器指定的。servlet容器用來加載這些庫文件的類加載器必須與在同一JVM中的全部Web應用的類加載器相同。此類加載器實例必須位於Web應用類加載器的父加載器鏈中。爲了保持移植性,應用開發者須要知道Web容器上安裝了什麼擴展,而且容器須要知道 WAR 中的 servlets 依賴哪些庫。依賴這些擴展的應用開發者必須在 WAR 文件中提供一個 META-INF/MANIFEST.MF 條目列出WAR須要的全部擴展。這個 manifest 條目的格式必須遵循標準的 JAR manifest 格式。在 Web 應用的部署中,Web 容器必須使擴展的正確版本對[遵照「可選包版本識別」機制定義規則]的應用可用。Web容器必須能識別 WAR 包中 WEB-INF/lib 目錄下的任何 JAR 庫中 manifest 條目裏聲明的依賴。若是Web容器不能知足以這種方式聲明的依賴,它應該使用一個有意義的錯誤信息拒絕應用。

10.7.2 Web應用類加載器


容器用來加載 WAR 中 servlet 的類加載器必須容許開發者使用 getResource 來加載[遵循正常 Java SE 詞法的] WAR 中 JAR 庫中包含的任何資源。在 Java EE 許可協議描述中,servlet 容器不是 Java EE 產品的一部分,不該該容許應用去覆蓋 Java SE 平臺類,好比 java.* 和 javax.* 中的類,Java SE 不容許被修改。容器不該該容許應用去覆蓋或者訪問容器的實現類。建議應用的類加載器實現爲:加載打包進WAR中的類和資源優先於加載容器範圍內的位於JAR庫中的類和資源。實現必須保證爲容器中部署的每個 web 應用調用 Thread.currentThread.getContextClassLoader() 必須返回一個實現了在本節中指定約定的 ClassLoader 實例。另外,每一個部署的 web 應用的 ClassLoader 實例必須是一個獨立的實例。在讓任何回調(包括 listener 回調)進入 web 應用以前,容器必須按照上面的描述設置線程上下文 ClassLoader(?),一旦回調返回,將它設置回原來的 ClassLoader。

10.8  替換 Web 應用

服務器應該能在不重啓容器的狀況下使用新版本替換應用。當應用被替換時,容器應該提供一個穩健的方法保留應用中的會話(session)數據。

10.9 錯誤處理

10.9.1 請求屬性

當錯誤發生時,Web 應用必須能指定應用中用來提供錯誤響應內容體的其它資源。這些資源的規範在部署描述符中設置。

若是錯誤處理的位置(the location of the error handler)是一個 servlet 或 一個 JSP 頁面:

▪  被容器建立的初始未包裝的請求和響應對象被傳遞給 servlet 或 JSP 頁面。

▪  請求路徑和屬性被設置爲:對錯誤資源的RequestDispatcher.forward 已經被執行同樣。(?)

▪  表10-1中的請求屬性必須被設置:

10-1 請求屬性和他們的類型

請求屬性                                                  類型

javax.servlet.error.status_code                java.lang.Integer

javax.servlet.error.exception_type           java.lang.Class

javax.servlet.error.message                    java.lang.String

javax.servlet.error.exception                   java.lang.Throwable

javax.servlet.error.request_uri                java.lang.String

javax.servlet.error.servlet_name             java.lang.String

這些屬性容許 servlet 根據狀態碼,異常類型,錯誤信息,傳播的異常對象,錯誤產生在其中的 servlet 處理的請求URI(由 getRequestURI 調用肯定)和錯誤產生的 servlet 的邏輯名來生成專門內容。

隨着本規範 2.3 版本中屬性列表中異常對象的引入,異常類型和異常信息屬性變得多餘。保留它們是爲了向後兼容API的早期版本。

10.9.2 錯誤頁面

爲了容許開發者自定義 servlet 產生錯誤時返回 Web 客戶端的內容的外觀(呈現),部署描述符定義了一系列錯誤頁面說明。 當 servlet 或 filter 爲特定狀態碼調用 response 的 sendError 或若是 servlet 產生的異常或錯誤傳播到了該容器時,此語法容許容器返回資源的配置。

若是 response 的 sendError 方法被調用,容器查詢Web應用的錯誤頁面聲明,使用狀態碼語法並嘗試匹配。若是有一個匹配,容器返回此位置(<location>)條目指示的資源。

容器或filter在處理請求期間可能會拋出下面的異常:

▪ runtime exceptions or errors 運行時異常或錯誤


▪ ServletExceptions 或 它的子類 


▪ IOExceptions or 或它的子類


Web應用可使用 exception-type 元素聲明錯誤頁面。在此狀況下,容器經過比較拋出的異常和使用 exception-type 元素定義的錯誤頁面(<error-page>)定義列表來匹配異常類型。匹配致使容器返回在位置(<location>)條目指示的資源。在類繼承層次最近的匹配勝出。  

若是使用類層次匹配沒有包含合適的 exception-type 的 error-page 聲明,而且拋出的異常是 ServletException 或它的子類,容器使用 ServletException.getRootCause 方法提出被包裝的異常。使用被包裝的異常(ServletException 或其子類中包裝的),再次傳入錯誤頁面聲明,從新嘗試匹配錯誤頁面聲明。

在部署描述符中使用 exception-type 元素的錯誤頁面(<error-page>)聲明中 exception-type 的類名必須是惟一的。一樣,使用 status-code  元素的  error-page 聲明在部署描述符中 status code 也必須是惟一的。

若是部署描述符中的一個 error-page 元素沒有包含 exception-type 或 error-code  元素,此錯誤頁面是默認錯誤頁面。

當使用  RequestDispatcher 或 filter.doFilter 方法調用發生錯誤時,錯誤頁面機制不會干預。在此種方式下,filter 或者 servlet 有機會使用 RequestDispatcher 處理產生的錯誤。(這段不知道對不對)

若是 servlet 產生的錯誤沒有被上面介紹的錯誤頁面機制處理,容器必須確保發送帶有狀態碼 500 的響應。

默認 servlet 和 container 將使用 sendError 方法發送 4XX 和 5XX 狀態響應,以便調用錯誤機制。默認 servlet 和 container 將使用 sendError 方法發送 2XX 和 3XX 狀態響應,不會調用錯誤機制。

若是應用(程序)使用在2.3.3.3節描述的異步操做,2-10頁的「異步處理」,應用程序負責處理應用程序建立的線程上的錯誤。容器【能夠】處理經過 AsyncContext.start 建立的線程產生的錯誤。參看2-16頁的幾節關於處理 AsyncContext.dispatch 期間產生的錯誤,「容器必須以下捕獲並處理 dispatch 方法執行期間可能產生的任何錯誤和異常」。

10.9.3 錯誤過濾器

錯誤頁面機制做用在容器產生的原始未包裝/未過濾的請求和響應對象上。此機制在 6.2.5 節描述,「過濾器和 RequestDispatcher」,在錯誤響應產生以前能夠用來指定應用的過濾器。

10.10 歡迎文件

Web應用開發者能夠在Web應用部署描述符中定義稱爲歡迎文件的[部分URI]有序列表。Web應用部署描述符 schema 中描述了此列表的部署描述符語法。

此機制的目的是容許開發者爲容器指定一個 部分的URIs 有序列表,當有對應 WAR 中一個目錄條目的 URI 的請求沒有映射到 Web 組件時,用來追加到這些 URI以後。這種類型的請求就是有名的 有效部分請求(a valid partial request)。

這種用法的好處經過下面的例子來搞清楚: 能夠定義一個 ‘index.html’ 的歡迎文件,以便對像 URL host:port/webapp/directory/ 的請求,’directory’ 是 WAR 裏一個沒有映射到 servlet 或 JSP page 的條目,返回給客戶端的是 ‘host:port/webapp/directory/index.html’。

若是Web容器接收到一個有效部分請求,Web容器必須檢查定義在部署描述符中的歡迎文件。歡迎文件列表是一個沒有前導和後導 / 的有順序的部分URL列表。Web 服務器必須按在部署描述符中指定的順序逐個添加歡迎文件到部分請求,而且檢查在WAR是否有一個靜態資源映射到請求的URI。若是沒有找到匹配,Web 服務器必須從新按照部署描述符中指定的順序依次添加每一個歡迎文件到部分請求並檢查是否有一個 servlet 映射到請求URI。Web 容器必須將請求發送到 WAR中匹配的第一個資源。容器可使用 forward,redirect 或容器指定的機制將請求發送到歡迎資源,與直接請求沒有什麼區別。

按照上面描述的方式若是沒有匹配的歡迎文件,容器能夠按照它能找到的合適方式來處理請求。對於某些配置可能意味着返回目錄列表,其它配置可能返回 404 響應。

考慮這樣的一個 Web 應用:

■ 部署描述符列出了下面的歡迎文件。

<welcome-file-list>

    <welcome-file>index.html</welcome-file>

    <welcome-file>default.jsp</welcome-file>

</welcome-file-list>

■ WAR中的靜態文件以下:

/foo/index.html

/foo/default.jsp

/foo/orderform.html

/foo/home.gif

/catalog/default.jsp

/catalog/products/shop.jsp

/catalog/products/register.jsp

▪   請求URI /foo 將會重定向到 URI /foo/。 


▪   請求URI /foo/ 將返回 /foo/index.html 。


▪   請求URI /catalog 將會重定向到 URI 
/catalog/。

▪   請求URI /catalog/ 將會返回 /catalog/default.jsp 。


▪    請求URI /catalog/index.html 將會致使 404 NOT FOUND.

▪   請求URI /catalog/products 將會重定向到 URI 
/catalog/products/。

▪   對URI /catalog/products/ 的請求將會傳遞到「默認」servlet, 若是有的話。若是沒有「默認」servlet 映射,此請求可能致使 404 not found , 可能致使包括 shop.jsp 和 register.jsp 的目錄列表,或者可能致使容器定義的其餘行爲。參見 12.2 節,「映射規範」中「默認」 servlet 的定義。 


▪   上面列出的全部靜態內容也能夠與上面打包進 jar 文件 META-INF/resources 目錄裏的內容一塊兒打包進 JAR 文件。此 JAR 文件能夠包含在 Web 應用的 WEB-INF/lib 目錄裏。 


10.11 Web應用環境

Servlet 容器不是 Java EE 技術標準的一部分,鼓勵實現但沒必要須,在 15.2.2 節「Web應用環境和Java EE規範」中描述了實現應用環境功能。若是它們(容器)沒有實現所需功能來支持[在上面部署應用所依賴]的環境,容器應該提供一個警告。

10.12  Web應用部署

當web應用被部署進容器,在web 應用開始處理客戶端的請求以前,必須按照下面的步驟依次執行:

▪    實例化在部署描述符中經過<listener>元素標識的每一個事件 listener 一個實例。

▪    爲每一個實現 ServletContextListener 的已實例化 listener 實例,調用 contextInitialized() 方法。

▪    實例化在部署描述符中經過 <filter> 元素標識的每一個 filter 的一個實例,而後調用每一個 filter 實例的 init() 方法。


▪   包含<load-on-startup> 元素的 <servlet> 元素標識的 servlet,按照 load-on- startup 元素值定義的(按由小到大)順序,每一個 servlet 實例化一個實例,而且調用每一個 servlet 的 init() 方法。 


10.13  包含web.xml部署描述符

若是web應用不包含任何 Servlet,Filter
或 Listener 組件,或者使用註解聲明瞭相同(就是使用了註解),不須要包含一個 web.xml 文件。換句話說,一個僅包括靜態文件或JSP頁面的應用不須要一個web.xml 來介紹。

相關文章
相關標籤/搜索