Servlet 3.1 行為變更
Servlet 3.1 實作含有一些行為變更,當您使用 Servlet 3.1 特性時,這些行為變更可能導致針對 Servlet 3.0 撰寫的應用程式行為異常或失敗。
您可以針對每一個伺服器實例,挑選 Servlet 3.0 或 Servlet 3.1 特性實作,並將行為變更納入考量。如果必要的行為只有 Servlet 3.1 特性才有,您必須使用 Servlet 3.1 特性。如果現有的應用程式會因 Servlet 3.1 特性中的行為變更,受到不利影響,則使用 Servlet 3.0 特性,可保留該應用程式的現有行為。在相同的伺服器中,不可能同時使用 Servlet 3.0 和 Servlet 3.1 特性。同時配置這兩個特性是錯誤的。如果您同時配置這兩個特性,沒有一個 Servlet 特性會載入。
- 為了闡明 Servlet 3.1 規格,所做的必要變更。
- 為了讓 Servlet 3.1 實作傳遞「Servlet 3.1 技術相容性套件 (TCK)」,所做的必要變更。
- 為了改良 Servlet 實作,所做的變更。
以程式設計方式新增 Servlet、過濾器和接聽器
Servlet 3.1 規格中現在有一項闡明,指出如果 ServletContextListener 未在 web.xml 檔或 web-fragment.xml 檔中宣告,或是未用 @WebListener 標註,則 ServletContextListener 以程式設計方式來配置 Servlet、過濾器或接聽器是不合法的。因此,只要呼叫 ServletContext 來執行這類程式化配置,會導致 UnsupportedOperationException。
啟動非同步處理程序之後的轉遞
在 Servlet 3.0 實作中,在傳回 RequestDispatcher 介面的 forward 方法之前,一律會先關閉回應。不過,就 Servlet 3.1 規格中的闡明來說,如果要求處於非同步模式,在傳回 RequestDispatcher 介面的 forward 方法之前,Servlet 3.1 實作不會關閉或清除回應。如果現有的 3.0 應用程式會在傳回時新增 forward 的回應輸出,可能受到這項變更的影響,因為現在會傳送這類回應資料,但在 Servlet 3.0 中卻不會。
URL 型樣衝突
SRVE9016E: Unable to insert mapping [{0}] for servlet named [{1}]. The URL pattern is already defined for servlet named [{2}].
Explanation: There is an application error. A servlet mapping URL pattern should not map to multiple servlets.
User action: Change the URL pattern for the servlet mapping.
ServletContext.getServerInfo()
在 Servlet 3.0 特性實作中,這個 API 會傳回 SMF WebContainer。
在 Servlet 3.1 特性中,現在這個 API 會傳回 IBM WebSphere Liberty/8.5.5.<x>,其中 <x> 是 WebSphere® Application Server 修正套件號碼。
ServletResponse.reset()
當回應尚未確定時,您可以使用 ServletResponse.reset(),來清除緩衝區中的任何回應資料、狀態碼和回應標頭。如果使用 Servlet 3.1 特性,此方法也會清除先前已呼叫的任何 ServletResonse.getWriter() 或 ServletResponse.getOutputStream() 記錄。
X-Powered-By 標頭
在 Servlet 3.0 特性實作中,X-Powered-By 標頭設為 Servlet/3.0。在 Servlet 3.1 特性實作中,X-Powered-By 標頭是設為 Servlet/3.1。
資源參照注入目標的合併
在 Servlet 3.0 規格中,如果同名的 web.xml 資源參照定義沒有任何 <injection-target> 元素,則只會將 web-fragment.xml 檔中所定義的資源參照 <injection-target> 元素,新增至母項 web.xml 檔。就 Servlet 3.1 規格中的闡明來說,會將 web-fragment.xml 描述子中的所有 <injection-target> 元素,新增至同名資源參照之 <injection-target> 元素的母項 web.xml 描述子清單。在使用 Servlet 3.1 特性期間,這個特性可能因啟動了先前已從 web.xml 檔排除的注入目標,而變更了現有應用程式功能。
對 Web 描述子中重複元素的容忍
就 Servlet 3.1 規格中的闡明來說,web.xml 檔不能包含兩個 <absolute-ordering> 元素。如果應用程式含有多個 <absolute-ordering> 元素,則會部署失敗。此外,web-fragment.xml 描述子不能包含兩個 <ordering> 元素。如果應用程式含有多個 <ordering> 元素,則會部署失敗。在以往,部署不會失敗,只是元素的功能可能不明確。
metadata-complete 案例中的網頁片段排序變更
如果將 web.xml 描述子標示為 metadata-complete="true",則 <absolute-ordering> 元素的處理方式已變更。以往在 metadata-complete="true" 案例中,將會使用所有的網頁片段保存檔。在使用 Servlet-3.1 特性期間,會將 metadata-complete 案例中的 <absolute-ordering> 元素視為待完成。這項變更會導致未列在 <absolute-ordering> 元素中的片段遭到排除,而不會加以處理。
AsyncContext.dispatch()
Request for /FirstResource?param=One
First Resource:
getParameter("param") returns "One"
forward request to /SecondResource?param=Two
SecondResource
getParameter(param) returns "Two"
ac.start()
ac.dispacth() dispatches to /FirstResource
First Resource
Servlet-3.0 feature : getParamter("param") returns "One"
Servlet-3.1 feature : getParameter("param") returns "Two"
This change was required by the Servlet 3.1 TCK.
SessionCookieConfig.setComment()
根據 Java™ Servlet 3.1 規格,如果在 ServletContext 完成起始設定之後呼叫這個 API,這個 API 會傳回 illegalStateException,且 Servlet-3.1 特性會遵循這個必要行為。不過,就 Servlet-3.0 特性來說,不會在起始設定環境定義之後阻止使用這個 API,如此一來,與 Servlet-3.0 特性行為相依的應用程式將無法與 Servlet-3.1 特性搭配運作。
sendRedirect(java.lang.String location) API
sendRedirect(java.lang.String location) API 接受相對 URL;不過,Servlet 儲存器必須將相對 URL 轉換成絕對 URL,才能將回應傳送給用戶端。如果是相對位置,且沒有前導的 '/' (folder/default.jsp),儲存器會將它解譯成現行要求 URI 的相對 URI。如果是相對位置,且有前導的 '/',儲存器會將它解譯成 Servlet 儲存器根目錄的相對 URI。
例如,如果應用程式提供的重新導向位置是 folder/default.jsp,沒有前導 '/',且入埠要求 URL 是 http://host:port/context_root/folder 或 http://host:port/context_root/folder/,則會將要求重新導向至 http://host:port/context_root/folder/folder/default.jsp,這是現行要求 URI 的相對 URL。
當 com.ibm.ws.webcontainer.redirectwithpathinfo 內容設為 true 時,會在 Servlet 3.0 特性中找到此行為。Servlet 3.1 特性中會忽略這個內容,並依照說明來預設其行為。
預設錯誤頁面
IBM® 延伸功能能夠使用 ibm-web-ext.xml 等之類的 Web 延伸,來指定預設錯誤頁面。
預設錯誤頁面是「指定錯誤頁面」功能的修正,這是 Servlet 3.0 和更新版本所提供的一項功能。當使用一般(非預設)錯誤頁面時,預設錯誤頁面是指定在 Web 模組描述子 (web.xml) 和網頁片段描述子 (web-fragment.xml) 中。
一般(非預設)錯誤頁面會指定 exception-type 或 error-code。預設錯誤頁面則同時省略了 exception-type 和 error-code。當 Servlet 擲出異常狀況或設定 error-code 結果時,如果所配置的錯誤頁面都不符合該異常狀況類型或所設定的錯誤碼,就會使用預設錯誤頁面。
「定義預設錯誤頁面」是 Servlet 3.0 規格提供的功能,Servlet 3.0 綱目也支援這項功能。根據 Servlet 3.1 規格,預設錯誤頁面是指不包含 exception-type 或 error-code 元素的錯誤頁面。
以下是錯誤頁面和預設錯誤頁面的範例。
- 預設錯誤頁面的優先順序規則
- 在判斷 web.xml、web-fragment.xml 和 ibm-web-ext.xml 檔中之預設錯誤頁面的優先順序時,會套用三條規則。
- 規則 1:web.xml 和 web-fragment.xml 檔。
如果 web.xml 檔中有指定預設錯誤頁面,它會置換(遮罩)web-fragment.xml 檔中指定的任何預設錯誤頁面。此外,如果有多個 web-fragment.xml 檔指定了預設錯誤頁面,則不會發生錯誤。
- 規則 2:web-fragment.xml 和 web-fragment.xml。
如果 web.xml 檔中沒有指定預設錯誤頁面,當有兩個或多個 web-fragment.xml 檔指定了不同的預設錯誤頁面,則會存在錯誤情況。
- 規則 3:ibm-web-ext.xml 和 web.xml 或 web-fragment.xml 檔。
ibm-web-ext.xml 檔與 web.xml 或 web-fragment.xml 檔之間的優先順序規則,取決於 Web 儲存器特性的層次。
當 Web 儲存器特性層次是 3.0,則 ibm-web-ext.xml 檔所定義的預設錯誤頁面的優先順序,高於 web.xml 或 web-fragment.xml 檔中所定義的預設錯誤頁面。註: 當 Web 儲存器使用特性層次 3.0 時,您無法使用 Servlet 3.1 綱目。請參閱 Servlet 3.0 綱目的預設錯誤頁面使用規則。當 Web 儲存器特性的層次是 3.1 或更新版本時,則 web.xml 或 web-fragment.xml 檔指定的預設錯誤頁面的優先順序,高於 ibm-web-ext.xml 檔中指定的預設錯誤頁面。
- 規則 1:web.xml 和 web-fragment.xml 檔。
- 綱目規則
不論是處理 web.xml 或 web-fragment.xml 檔中的預設錯誤頁面,都會套用兩條規則。這些規則取決於 Web 儲存器特性的版本、正在使用的 Servlet 綱目,以及 Java 自訂內容的設定。
由於 IBM WebSphere Application Server 8.0 版完整設定檔在 8.0 版通用版次中不支援預設錯誤頁面,才會有這些規則出現。APAR PM94199 已在服務套件中,將預設錯誤頁面支援新增至應用程式伺服器完整設定檔。APAR PI05845 已在服務套件中,將預設錯誤頁面支援新增至應用程式伺服器 Liberty 設定檔。由於這些更新項目是外部可見功能的變更,依預設,會停用新功能,必須使用 Java 系統內容來啟用它。
- 規則 1:使用 Servlet 3.0 綱目和使用 Web 儲存器特性 3.0 版時的預設錯誤頁面。
當 Web 儲存器特性是 3.0 版,且使用 Servlet 3.0 綱目的 web.xml 或 web-fragment.xml 檔中有指定預設錯誤頁面時,則只有在 com.ibm.ws.webcontainer.allowdefaulterrorpage Java 系統內容設為 true 時,才會處理預設錯誤頁面。如果這個 Java 系統內容未設定,或不是設為 true 時,就會忽略預設錯誤頁面。會採用 ibm-web-ext.xml 檔指定的預設錯誤頁面。
- 規則 2:使用 Web 儲存器特性 3.1 版時的預設錯誤頁面。
當 Web 儲存器特性是 3.1 版或更新的版本時,一律處理 web.xml 檔或 web-fragment.xml 檔中指定的預設錯誤頁面,而不考慮使用的 Servlet 綱目版本,也不考慮是否設定 Java 自訂內容。
當描述子使用 Servlet 3.1 綱目時就會發生此情況,因為在處理使用 Servlet 3.1 綱目的描述子時,需要 Web 儲存器特性 3.1 版。
- 規則 1:使用 Servlet 3.0 綱目和使用 Web 儲存器特性 3.0 版時的預設錯誤頁面。
- 錯誤頁面和預設錯誤頁面範例
- ibm-web-ext.xml 檔中指定的預設錯誤頁面。
<?xml version="1.0" encoding="UTF-8"?> <web-ext xmlns="http://websphere.ibm.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_0.xsd" version="1.0"> <default-error-page uri="/ExtErrorPage.html"/> </web-ext>
- web.xml 檔或 web-fragment.xml 檔中定義的 error-code 錯誤頁面元素:
<error-page> <error-code>404</error-code> <location>/ErrorCodeErrorPage.html</location> </error-page>
- web.xml 檔或 web-fragment.xml 檔中定義的 exception-type 錯誤頁面元素:
<error-page> <exception-type>javax.servlet.ServletException</exception-type> <location>/ExceptionTypeErrorPage.html</location> </error-page>
- web.xml 檔或 web-fragment.xml 檔中定義了一個預設錯誤頁面元素:
<error-page> <location>/DefaultErrorPage.html</location> </error-page>
- 綱目範例
- 使用 Servlet 2.5 綱目的 web.xml 檔標頭範例:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
- 使用 Servlet 3.0 綱目的 web.xml 檔標頭範例:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
- 使用 Servlet 3.1 綱目的 web.xml 檔標頭範例:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
- 使用 Servlet 3.0 綱目的 web-fragment.xml 檔標頭範例:
<?xml version="1.0" encoding="utf-8"?> <web-fragment xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd" version="3.0">
- 使用 Servlet 3.1 綱目的 web-fragment.xml 檔標頭範例:
<?xml version="1.0" encoding="utf-8"?> <web-fragment xmlns="http://java.sun.com/xml/ns/javaee" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-fragment_3_1.xsd" version="3.1">