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.getMinorVersion()
在 Servlet 3.0 特性實作中,這個 API 會傳回 0。
在 Servlet 3.1 特性中,現在這個 API 會傳回 1。
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.
java.lang.IllegalStateException: SRVE9015E: Cannot obtain the request or response object after an AsyncContext.dispatch() or AsyncContext.complete().
at com.ibm.ws.webcontainer31.async.AsyncContext31Impl.getRequest(AsyncContext31Impl.java:72)
[...]
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 traditional 8.0 版在 8.0 版通用版次中不支援預設錯誤頁面,才會有這些規則出現。 APAR PM94199 已在服務套件中,將預設錯誤頁面支援新增至 WebSphere Application Server traditional。 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">