Servlet3.1標準學習筆記

Servlet3.1標準學習筆記

1.Servlet默認是線程不安全的,需要開發人員處理多線程問題。

通常Web容器對於併發請求將使用同一個servlet處理,並且在不同的線程中併發執行service方法。

2.doPutdoDelete方法允許Servlet開發人員讓支持HTTP/1.1的客戶端使用這些功能。HttpServlet中的doHead 方法可以認爲是doGet方法的一個特殊形式,它僅返回由doGet 方法產生的header 信息。doOptions方法返回當前servlet支持的HTTP方法(譯者注:通過Allow響應頭返回支持的HTTP 操作,如GETPOST)。 doTrace方法返回的響應包含TRACE 請求的所有頭信息。

3.HttpServlet 定義了用於支持有條件GET 操作的getLastModified 方法。所謂的有條件GET 操作是指客戶端 通過GET請求獲取資源時,當資源自第一次獲取那個時間點發生更改後纔再次發生數據,否則將使用客戶端緩存的數據。在一些適當的場合,實現此方法可以更有效的利用網絡資源,減少不必要的數據發送。

4.對於未託管在分佈式環境中(默認)的servlet而言,servlet容器對於每一個Servlet聲明必須且只能產生一個實例。不過,如果Servlet實現了SingleThreadModel接口,servlet容器可以選擇實例化多個實例以便處理高負荷請求或者串行化請求到一個特定的實例。

如果Servlet以分佈式方式進行部署,容器可以爲每個虛擬機(JVM)的每個Servlet聲明產生一個實例。但是,如果在分佈式環境中servlet實現了SingleThreadModel接口,此時容器可以爲每個容器的JVM實例化多個Servlet實例。

5.SingleThreadModel接口的作用是保證一個特定的servlet實例的service方法在一個時刻僅能被一個線程執行,一定要注意,此包裝僅適用於每一個servlet實例,因此容器可以選擇池化這些對象。有些對象可以在同一時刻被多個servlet實例訪問,如HttpSession實例,可以在一個特定的時間對多個Servlet可用,包括哪些實現了SingleThreadModel接口的Servlet

6.Servlet容器通過調用Servlet實例的init方法完成初始化,init方法定義在Servlet接口中,並且提供一個唯一的ServletConfig接口實現的對象作爲參數,該對象每個Servlet實例一個。配置對象允許Servlet訪問由Web應用配置信息提供的鍵值對的初始化參數。該配置對象也提供給Servlet去訪問一個ServletContext對象,ServletContext描述了Servlet的運行時環境。

7.客戶端請求由ServletRequest類型的request對象表示。Servlet封裝響應並返回給請求的客戶端,該響應由ServletResponse類型的response表示。這兩個對象(requestresponse)是由容器通過參數傳遞到Servlet接口的service方法的。

HTTP請求的場景下,容器提供的請求和響應對象具體類型分別是HttpServeltRequestHttpServletResponse。需要注意的是,由Servlet容器初始化的某個Servlet實例在服務期間,可以在生命週期中不處理任何請求。

8.ServletException表示在處理請求過程中發生了錯誤,容器應該採取適當措施清理請求。

UnavailableException表示servlet不能處理請求,可能是臨時的也可能是永久的。如果UnavailableException表示的是一個永久性的不可用,Servlet容器必須從服務中移除這個Servlet,調用它的destory方法,並釋放Servlet實例。所有被容器拒絕的請求,都會返回一個SC_NOT_FOUND(404)響應。

如果UnavailableException表示的是一個臨時性的不可用,容器可以選擇在臨時不可用的這段時間內路由任何請求到Servlet。所以在這段時間內被容器拒絕的請求,都會返回一個SC_SERVICE_UNAVAILABLE(503)響應狀態碼,且同時會返回一個Retry-After頭指示此Servlet什麼時候可用。容器可選擇忽略永久性和臨時性不可用的區別,並把UnavailableExceptions視爲永久性的,從而Servlet拋出UnavailableException後需要把它從服務中移除。

9.Servelet3.0引入了異步處理請求的能力,是線程可以返回到容器,從而執行更多的任務。當開始移除處理請求時,另一個線程或回調可以或者產生響應,或者調用完成(complete)或者請求分派(dispatch),這樣,它可以在容器上下文使用AsyncContext.dispatch方法運行。

從一個Servlet分派時,把asyncSupported=true設置爲false是允許的。這種情況下,當servletservice方法不支持異步退出時,響應將被提交,且容器負責調用AsyncContextcomplete,以便所有感興趣的AsyncListener得到觸發通知。過濾器作爲清理要完成的異步任務持有的資源的一種機制,也應該使用AsyncListener.onComplete觸發的結果。

從一個同步Servlet分派到另一個異步Servlet是非法的。不過與改點不同的是當應用調用startAsync時將拋出IllegalStateException。這將允許servlet只能作爲同步的或異步的Servlet

10.AsyncContext該類表示在ServletRequest啓動的異步操作執行上下文,AsyncContext由之前描述的ServletRequest.startAsync創建並初始化。

任何執行dispath方法期間可能拋出的錯誤或異常必須由容器捕獲及處理:

1)調用所有由AsyncContext創建的並註冊到ServletRequestAsyncListener實例的AsyncListener.onError(AsyncEvent)方法,可以通過AsyncEvent.getThrowable()獲取到捕獲的Throwable

2)如果沒有監聽器調用AsyncContext.complete或任何AsyncContext.dispatch方法,然後執行一個狀態碼爲HttpServletResponse.SC_INTERNAL_SERVER_ERROR的出錯分派,並且可以通過RequDispatcher.ERROR_EXCEPTION請求屬性獲取Throwable值。

3)如果沒有找到匹配的錯誤頁面,或錯誤頁面沒有調用AsyncContext.complete()或任何AsyncContext.dispatch方法,則容器必須調用AsyncContext.complete

在異步操作超時的情況下,容器必須按照如下步驟運行:

1)當異步操作啓動後調用註冊到ServletRequest的所有AscyncListener實例的AsyncListener.onTimeout方法

2)如果沒有監聽器調用AsyncContext.complete()或任何AsyncContext.dispatch方法,執行一個狀態碼爲HttpServletResponse.SC_INTERNAL_SERVER_ERROR出錯分派。

3)如果沒有找到匹配的錯誤頁面,或者錯誤頁面沒有調用AsyncContext.complete()或者任何Asyn.dispath方法,則容器必須調用AsyncContext.complete()

如果在AsyncListener中調用的方法拋出異常,將記錄下來且將不影響任何其他AsyncListener的調用。

默認情況下是不支持JSP的異步處理,因爲它是用於內容審查且異步處理可能在內容生成之前已經完成。這取決於如何處理這種情況。一旦完成了所有的異步活動,使用AsyncContext.dispatch分派到的JSP頁面可以用來生成內容。

11.HTTP/1.1Upgrade通用頭(general-header)允許客戶端指定其支持和希望使用的其他通信協議。如果服務器找到合適的切換協議,那麼新的協議將在之後的通信中使用。Servlet容器提供了HTTP升級機制。不過,Servlet容器本身不知道任何升級協議。協議處理封裝在HttpUpgradeHandler協議處理器。在容器和HttpUpgradeHandler協議處理器之間通過字節流進行數據讀取或寫入。

當收到一個升級(upgrade)請求,servlet可以調用HttpServletRequest.upgrade方法啓動升級處理。該方法實例化給定的HttpUpgradeHandler類,返回的HttpUpgradeHandler實例可以被進一步定製。應用準備和發送一個合適的響應到客戶端。退出servlet service方法之後,servlet容器完成所有過濾器的處理並標記連接已交給HttpUpgradeHandler協議處理器處理。然後調用HttpUpgradeHandler協議處理器init方法,傳入一個WebConnection以允許HttpUpgradeHandler協議處理器訪問數據流。

Servlet過濾器僅處理初始的HTTP請求和響應,然後他們將不會再參與到後續的通信中。換句話說,一旦請求被升級,它們將不會被調用。

協議處理器(ProtocolHandler)可以使用非阻塞IO接收和發送消息。

當處理HTTP升級時,開發人員負責線程安全的訪問ServletInputStreamServletOutputStream

當升級處理已經完成,將調用HttpUpgradeHandler.destory方法。

12.servlet的請求參數以字符串的形式作爲請求的一部分從客戶端發送servlet容器。當請求時一個HttpServletRequest對象,且符合下面參數可用時描述的條件時,容器從URI查詢字符串和POST數據中填充參數。參數以一系列的名值對的形式保存。任何給定的參數和名稱可存在多個參數值。

以下是在POST表單數據填充到參數集前必須滿足的條件:

1)該請求是一個HTTP或者HTTPS請求。

2HTTP請求的方法是POST

3)內容類型是application/x-www-form-urlencoded.

4)該servlet已經對request對象的任意getPararmeter方法進行了初始調用。

13.當數據以multipart/from-data的格式發送時,servlet容器支持文件上傳

1servlet處理註解“@MultipartConfig”標註的請求。

2)爲了servlet處理請求,部署描述符包含了一個multipart-config元素。

如果servlet容器提供multipart/form-data格式數據的處理,可以同HttpServletRequset中的以下方法得到:

1public Collection<Part> getParts()

2public Part getPart(String name)

注:Part類代表從multipart/from-data格式的POST請求中接收到的一個部分或表單項。每個part都可通過Part.getInputStream方法訪問頭部,相關的內容類型和內容。

對於表單數據的Content-Disposition,即使沒有文件名,也可使用part的名稱通過HttpServletRequestgetParametergetParameterValues方法得到part的字符串值。

如果servlet的容器不提供multi-part/form-data格式數據的處理,這些數據將可通過HttpServletRequest.getInputStream得到。

14.屬性是與請求相關聯的對象。屬性可以由容器設置來表達信息,否則無法通過API標示,或者由servlet設置將信息傳達給另一個servlet(通過RequestDispatcher)。屬性通過ServletRequest接口中下面的方法來訪問:

1getAttribute

2getAttributeNames

3setAttribute

只有一個屬性值可與一個屬性名稱相關聯。以前綴java.javax.開頭的屬性名稱是本規範的保留定義。同樣地,以前綴sun.com.sun.oraclecom.oracle開頭的屬性名是Oracle Corporation的保留定義。

15.引導servlet服務請求的請求路徑由許多重要部分組成。以下元素從請求URI路徑得到,並通過request對象公開:

1Context Path:與ServletContext相關聯的路徑前綴是這個servlet的一部分。如果這個上下文是基於Web服務器的URL命名空間基礎上的默認上下文,那麼這個路徑將是一個空字符串。否則,如果上下文不是基於服務器的命名空間,那麼這個路徑以"/" 字符開始,但不以"/" 字符結束。

2Servlet Path:路徑部分直接與激活請求的映射對應。這個路徑以"/"字符開頭,如果請求與"/*"“”模式匹配,在這種情況下,它是一個空字符串。

3PathInfo:請求路徑的一部分,不屬於Context PathServlet Path。如果沒有額外的路徑,它要麼是null,要麼是以"/"開頭的字符串。

重要的是要注意,除了請求URI和路徑部分的URL編碼差異外,下面的等式永遠爲真:

reuqestURI=contextPath+servletPath+pathInfo

16.API中有兩個方便的方法,允許開發者獲得與某個特定的路徑等級的文件系統路徑。這些方法是:

1ServletContext.getRealPath

2HttpServletRequest.getPathTranslated

getRealPath方法需要一個字符串參數,並返回一個字符串形式的路徑,這個路徑對應一個在本地文件系統上的文件。getPathTranslated方法推斷出請求的pathInfo的實際路徑。

這些方法在servlet容器無法確定一個有效的文件路徑的情況下,如Web應用程序從歸檔中,在不能訪問本地的遠程文件系統上,活在一個數據庫中執行時,這些方法必須返回nullJAR文件中META-INF/resources目錄下的資源,只有當調用getRealPath()方法時才認爲容器已經從包含它的JAR文件中解壓,在這種情況下,必須返回解壓縮後的位置。

17.servlet容器的非阻塞IO允許開發人員在數據可用時讀取數據或在數據可寫時寫數據。非阻塞IO僅對在ServletFilter中的異步請求處理和升級處理有效。否則,當調用ServletInputStream.setReadListenerServletInputStream.setWriteListener方法時將拋出IllegalStateException

一旦把監聽器與給定的ServletInputStream關聯起來,當數據可以讀取,所有的數據都讀取完或如果處理請求時發生錯誤,容器調用ReadListener的方法。註冊一個ReadListener將啓動非阻塞IO。在那時切換到傳統的阻塞IO是非法的,且必須拋出IllegalStateException。在當前請求範圍內,隨後調用setReadListener是非法的且必須拋出IllegalStateException

18.HttpServletRequest接口提供了getCookies方法來獲得請求中的cookie的一個數組。這些cookie是從客戶端發送到服務器端的客戶端發出的每個請求上的數據。

如果請求已經通過一個安全協議發送過,如HTTPS,必須通過ServletRequest接口的isSecure方法公開該信息。Web容器必須公開下列屬性給servlet程序員:

密碼套件               javax.servlet.request.cipher_suite                 String

算法的位大小        javax.servlet.request.key_size                        Integer

SSL會話id             javax.servlet.request.ssl_session_id               String

如果有一個與請求相關的SSL證書,它必須由servlet容器以java.security.cert.X509Certificate類型的對象數組暴露給servlet程序員並可通過一個javax.servlet.request.X509Certificate類型的ServletRequest屬性訪問。

19.客戶端可以選擇希望Web服務器用什麼語言來響應。該信息可以和使用Accept-Language頭與HTTP/1.1規範中描述的其他機制的客戶端通信。

1getLocale    返回客戶端請求要接受內容的首選語言環境。

2getLocales   返回一個Locale對象的枚舉,從首選語言環境開始順序遞減,這些語言環境是可被客戶接受的語言環境。

如果客戶端沒有指定首選語言環境,getLocale方法返回的語言環境必須是servlet容器默認的語言環境,而getLocales方法必須返回只包含一個默認語言環境的Local元素的枚舉。

20.許多瀏覽器不隨着Content-Type頭一起發送字符編碼限定符,而是根據讀取HTTP請求確定字符編碼。如果客戶端請求沒有指定請求默認的字符編碼,容器用來創建請求讀取器和解析POST數據的編碼必須是“ISO-8859-1”。然而,爲了向開發人員說明客戶端沒有請求默認的字符編碼,在這種情況下,客戶端發送字符編碼失敗,容器從getCharacterEncoding 方法返回null.

如果客戶端沒有設置字符編碼,並使用不同的編碼來編碼請求數據,而不是使用上面描述的默認的字符編碼,那麼可能會發生數據損壞。Servlet接口添加了一個新的方法,setCharacterEncoding(String enc)。開發人員可以通過調用該方法來覆蓋由容器提供的字符編碼。必須在解析任何post數據或從請求讀取任何輸入之前調用此方法。此方法一旦調用,將不會影響已經讀取的數據的編碼。

21.每個request對象只在servletservice方法的作用域內,或過濾器的doFilter方法的作用域內有效,除非該組件啓用了異步處理並且調用了request對象的startAsync方法。在發生異步處理的情況下,request對象一直有效,知道調用AsyncContextcomplete方法。容器通常會重複利用request對象,以避免創建request對象的性能開銷。開發人員必須注意的是,不建議在上述範圍之外保持startAsync方法還沒有被調用的請求對象的引用,因爲這樣可能產生不確定的結果。

在請求升級的情況下,如上描述依然成立。

22.ServletContextServlet上下文)接口定義了servlet運行在的Web應用的視圖。容器供應商負責提供Servlet容器的ServletContext接口的實現。Servlet可以使用ServletContext對象記錄事件,獲取URL引用的資源,存錢當前上下文的其他Servlet可以訪問的屬性。

ServletContextWeb服務器中已知路徑的根。例如,Servlet上下文可以從http://www.mycorp.com/catalog找出,/catalog請求路徑稱爲上下文路徑,所有以它開頭的請求都會被路由到與ServletContext相關聯的Web應用。

部署在容器中的每一個Web應用都有一個ServletContext接口的實例與之關聯。在容器分佈在多態虛擬機的情況下,每個Web應用在每個JVM中都將有一個ServletContext實例。

如下ServletContext接口方法允許Servlet訪問由應用開發人員在Web應用中的部署描述符中指定的上下文初始化參數:

1getInitParameter

2getInitParameterNames

應用開發人員使用初始化參數來表達配置信息。

如下的方法只能在應用實例化的過程中通過一個ServletContextListener實現的contextInitialized方法或者一個ServletContainerInitializer實現的onStartup方法調用。除了添加ServletFilter,也可以查找關聯到ServletFilter的一個Registraction對象實例,或者到Servlet或者Filter的所有Registration對象的map

ServletContext添加指定class名稱的監聽器。ServletContext將使用由與應用關聯的classloader裝載加載該給定名稱的class,且它們必須實現一個或多個以下接口:

1javax.servlet.ServletContextAttributeListener

2javax.servlet.ServletRequestListener

3javax.servlet.ServletRequestAttributeListener

4javax.servlet.http.HttpSessionListener

5javax.servlet.http.HttpSessionAttributeListener

6javax.servlet.http.HttpSessionIdListener

如果ServletContext傳到了ServletContainerInitializeronStartup方法,則給定名字的類可以實現除上面列出的接口之外的javax.servlet.ServletContextListener。作爲該方法調用的一部分,容器必須裝載指定類名的class,以確保其實現了所需的接口之一。如果給定名字的類實現了一個監聽器接口,則其調用順序和聲明順序是一樣的。換句話說,如果它實現了javax.servlet.ServletRequestListenerjavax.servlet.http.HttpSessionListener,那麼新的監聽器將被添加到該接口的有序監聽器列表的末尾。

23.上下文屬性

Servlet可以使用指定的名字將對象屬性綁定到上下文。同一個Web應用內的其他任何Servlet可以使綁定到上下文的任意屬性。

JVM中創建的上下文屬性是本地的,這可以防止從一個分佈式容器的共享內存存儲中獲取ServletContext屬性,當需要在運行在分佈式環境的Servlet之間共享信息時,該信息應該被放到session或存儲到數據庫,或者設置到企業級JavaBean組件。

24.資源

ServletContext接口提供了直接訪問Web應用中靜態內容層次機構的文件的方法,包括HTMLGIFJPEG文件

1getResource

2getResourceAsStream

getResourcegetResourceAsStream方法需要一個以“/”開頭的String字符串作爲參數,給定的資源路徑是相對於上下文的根,或者相對於web應用的WEB-INF/lib目錄下的JAR文件中的META-INF/resources目錄。這兩個方法首先根據請求的資源查找web應用上下文的根,然後查找所有WEB-INF/lib目錄下的JAR文件。查找WEB-INF/lib目錄中JAR文件的順序是不確定的。這種層次結構的文件可以存在於服務器的文件系統,Web應用的歸檔文件,遠程服務器,或者其他位置。

這兩個方法不能獲取動態內容。

25.Servlet上下文不會在虛擬主機之間共享。ServletContext接口的getVirtualServerName方法允許訪問ServletContext部署在的邏輯主機的配置名字。該方法必須對所有部署在邏輯主機上的所有servlet context返回同一個名字。且該方法返回的名字必須是明確的、每個邏輯主機穩定的、和適合用於關聯服務器配置信息和邏輯主機。

26.每一個servlet上下文都需要一個臨時的存儲目錄。Servlet容器必須爲每一個servlet上下文提供一個私有的臨時目錄,並將通過javax.servlet.context.tempdir上下文屬性使其可用,關聯該屬性的對象必須是java.io.File類型。該要求公認爲在多個servlet引擎實現中提供一個通用的便利。當servlet容器重啓時,它不需要去保持臨時目錄中的內容,但必須確保一個servelt上下文的臨時目錄中的內容對運行在同一個servlet容器的其他Web應用的上下文不可見。

27.響應對象封裝所有從服務器返回給客戶端的信息,在HTTP協議中,從服務器返回客戶端的信息是通過HTTP頭信息或請求的信息體傳輸的。

ServletResponse接口的如下方法運行servlet訪問和設置緩衝信息:

1getBufferSize 返回使用的底層緩衝區大小。如果沒有使用緩衝,該方法必須返回一個int0.

2setBufferSize  Servlet可以請求setBufferSize方法設置一個最佳的緩衝大小。

3isCommitted 返回一個表示是否有任何響應字節已經返回到客戶端的boolean值。 

4reset 當響應沒有提交時,該方法情況緩衝區的數據。頭信息,狀態碼和在調用reset之前servlet調用getWritergetOutputStream設置的狀態也必須被清空。

5resetBuffer 如果響應沒有被提交,該方法將清空緩存區的內容,但不清空請求頭和狀態碼。

6flushBuffer 強制刷出緩衝區的內容到客戶端

Servlet可以使用如下HttpServletResponse接口中的方法設置HTTP響應頭:

1setHeader 設置一個給定名字和值的header。之前的header將被新的header替換。

2addHeader方法使用給定的名字添加一個header值到set

28.非阻塞IO

非阻塞IO僅對在ServletFilter中的異步請求處理和升級處理有效。否則,當調用ServletInputStream.setReadListenerServletOutputStream.setWriteListener方法時將拋出IllegalStateException

29.HttpServletResponse提供瞭如下簡便方法:

1sendRedirect 將設置適當的header和內容體將客戶端重定向到另一個地址。使用相對URL路徑調用該方法是合法的,但是底層的容器必須將傳回到客戶端的相對地址轉換爲全路徑URL

2sendError 方法將設置適當的header和內容體用於返回給客戶端返回錯誤消息。可以爲sendError方法提供一個可選的String參數用於指定錯誤的內容體。

30.Servlet應設置responselocale和字符集。使用ServletResponse.setLocal方法設置local。該方法可以重複調用;但相應被提交後調用該方法不會產生任何作用。如果在頁面被提交之前Servlet沒有設置locale,容器的默認locale將用來確定相應的locale,但是沒有指定與客戶端通信的規範,例如使用HTTP情況下的Context-Language header

setCharacterEncodingsetContentTypesetLocale方法可以被重複的調用來改變字符編碼。

ServletResponse接口的getWriter方法被調用或響應被提交之前,如果servlet沒有指定字符編碼,默認使用ISO-8859-1

當響應被關閉時,容器必須立即刷出響應緩衝區中的所有剩餘的內容到客戶端。

以下事件表明servlet滿足了請求且響應對象即將關閉:

1servletservice方法終止。

2)響應的setContentLengthsetContentLengthLong方法制定了大於零的內容量,且已經寫入到響應。

3sendError方法已調用

4sendRedirect方法已調用。

5AsyncContextcomplete方法已調用。

每個響應對象是隻有當在servletservice方法的範圍內或在filterdoFilter方法範圍內是有效的,除非該組件關聯的請求對象已經開啓異步處理。如果相關的請求已經啓動異步處理,那麼知道AsyncContextcomplete方法被調用,請求對象一直有效。爲了避免響應對象創建的性能開發,容器通常回收響應對象。在相關的請求的startAsync還沒有調用時,開發人員必須意識到保持到響應對象引用,超出之上描述的範圍可能導致不確定的行爲。

31.過濾器是一種代碼重用的技術,它可以改變HTTP請求的內容,響應,及header信息。過濾器通常不產生響應或像servlet那樣對請求作出響應,而是修改或調整到資源的請求,修改或調整來自資源的響應。

供開發人員使用的過濾器功能有如下幾種類型:

1)在執行請求之前訪問資源

2)在執行請求之前處理資源的請求

3)用請求對象的自定義版本包裝請求,對請求的header和數據進行修改

4)用響應對象的自定義版本包裝響應,對響應的header和數據進行修改。

5)攔截資源調用之後的調用

6)按指定順序執行的零個、一個或多個攔截器作用於Servlet,一組Servlet或靜態內容

應用開發人員通過實現javax.servlet.Filter接口並提供一個公共的空參構造器來創建過濾器。該類及構建Web應用的靜態資源和Servlet打包在Web應用歸檔文件中。Filter在部署描述符中通過<filter>元素聲明。一個過濾器或一組過濾器可以通過在部署描述符中定義<filter-mapping>來爲調用配置。可以使用servlet的邏輯視圖名把過濾器映射到一個特定的servlet,或者使用URL模式把一組Servlet和靜態資源內容映射到過濾器。

在部署描述符中聲明的每個<filter>在每個JVM的容器中僅實例化一個實例。容器提供了聲明在過濾器的部署描述符的過濾器configFilterConfig),對Web應用的ServletContext的引用,和一組初始化參數。

過濾器的核心概念是包裝請求或響應,以便它可以覆蓋行爲執行過濾任務。在這個模型中,開發人員不僅可以覆蓋請求和響應對象上已有的方法,也能提供新的API以適用於對過濾器鏈中剩下的過濾器或目標web資源做特殊的過濾任務。

32.可以使用部署描述符中的<init-params>元素把一組初始化參數關聯到過濾器。這些參數的名字和值在過濾器運行期間可以使用過濾器的FilterConfig對象的getInitParametergetInitParameterNames方法得到。另外,FilterConfig提供訪問Web應用的ServletContext用於加載資源,記錄日誌,在ServletContext的屬性列表存儲狀態。鏈中最後的過濾器和目標servlet或資源必須執行在同一個調用線程。

過濾器可以通過@WebFilter註解定義或者在部署描述符中使用<filter>元素定義。在這個元素中,可聲明如下內容:

1filter-name:用於映射過濾器到servletURL

2filter-class:由容器用於標示過濾器類型

3init-params:過濾器的初始化參數

容器必須爲部署描述符中定義的每個過濾器聲明實例化一個Java類實例。因此,如果開發人員對一個過濾器類聲明瞭兩次,則容器將實例化兩個相同的過濾器類的實例。

一旦在部署描述符中聲明瞭過濾器,配置人員使用<filter-mapping>定義Web應用中的servlet和靜態資源到過濾器的應用。過濾器可以使用<servlet-name>元素關聯到一個Servlet。過濾器可以使用<url-pattern>風格的過濾器映射關聯到一組servlet和靜態內容。

當使用<url-pattern>風格配置<filter-mapping>元素,容器必須使用路徑映射規則(path mapping rule)決定<url-pattern>是否匹配請求URI

容器使用的用於構建應用到一個特定請求URI的過濾器鏈的順序如下所示:

1)首先,<url-pattern>按照在部署描述符中的出現順序匹配過濾器映射。

2)接下來,<servlet-name>按照在部署描述符中的出現順序匹配過濾器映射。

如果過濾器映射同時包含了<servlet-name><url-pattern>,容器必須展開過濾器映射爲多個過濾器映射(每一個<servlet-name><url-pattern>一個),保持<servlet-name><url-pattern>元素順序。

33.通過在部署描述符中使用心得<dispatcher>元素,開發人員可以爲filter-mapping指定是否想要過濾器應用到請求,當:

1)請求直接來自客戶端

可以由一個帶有REQUEST值的<dispatcher>元素,或者沒有任何<dispatcher>元素來表示。

2)使用表示匹配<url-pattern><servlet-name>web組件的請求分配器的forward()調用情況下處理請求。

可以由一個帶有FORWARD值的<dispatcher>元素表示。

3)使用表示匹配<url-pattern><servlet-name>Web組件的請求分派器的include()調用情況下處理請求。

可以由一個帶有INCLUDE值的<dispatcher>元素表示。

4)使用第106錯誤處理指定的錯誤頁面機制處理匹配<url-pattern>的錯誤資源的請求。

可以由一個帶有ERROR值的<dispatcher>元素表示。

5)使用第10頁指定的異步處理中的異步上下文分派機制對web組件使用dispatche調用處理請求。

可以由一個帶有ASYNC值的<dispatcher>元素表示。

6)或之上1,2,3,4,5的任何組合。

34.HTTP被設計爲一種無狀態協議。爲了構建有效的Web應用,必須與來自一個特定的客戶端的請求彼此相關關聯。

1Cookies

通過HTTP cookie的會話跟蹤是最常用的會話跟蹤機制,且所有servlet容器都應該支持。

容器向客戶端發送一個cookie,客戶端後續到服務器的請求都將返回該cookie,明確地將請求與會話關聯。會話跟蹤cookie的標準名字必須是JSESSIONID,所有3.0兼容的容器必須支持。容器也允許通過容器指定的配置自定義會話跟蹤cookie的名字。

2SSL會話

安全套接字層,在HTTPS使用的加密技術,有一種內置機制允許多個來自客戶端的請求被明確識別爲同一會話。Servlet容器可以很容易地使用該數據來定義會話。

3URL重寫

URL重寫是會話跟蹤的最低標準。當客戶端不接受cookie時,服務器可使用URL重寫作爲會話跟蹤的基礎。URL重寫設計添加數據、會話ID、容器解析URL路徑從而請求與會話相關聯、

會話ID必須被編碼爲URL字符串中的一個路徑參數。參數的名稱必須是jessionid.

URL重寫在日誌、書籤、refer header、緩存的HTMLURL工具條中暴露會話標識。在支持cookieSSL會話的情況下,不應該使用URL重寫作爲會話跟蹤機制。

與每個會話相關聯的是一個包含唯一標識符的字符串,也被稱爲會話ID,會話ID的值能通過調用javax.servlet.http.HttpSession.getId()獲取,且能在創建後通過調用javax.servlet.http.HttpServletRequest.changeSessionId()改變。

HttpSession對象必須被限定在應用(或servlet上下文)級別。底層的機制,如使用cookie建立會話,不同的上下文可以是相同,但所引用的對象,包括該對象中的屬性,決不能在容器上下文之間共享。

35.servlet可以按名稱綁定對象屬性到HttpSession實現,任何綁定到會話的對象可用於任意其他的Servlet,其屬於同一個ServletContext且處理屬於相同會話中的請求。

一些對象可能需要在它們被放進會話或從會話中移除時得到通知。這些信息可以從HttpSessionBingingListener接口實現的對象中獲取。這個接口定義了以下方法,用於標識一個對象被綁定到會話或從會話解除綁定時。

1valueBound

2valueUnbound

Servlet容器定義了默認的會話超時時間,且可以通過HttpSession接口的getMaxInactiveInterval方法獲取,也可以通過setMaxInactiveInterval方法設置超時時間。

HttpSession接口的getLastAccessedTime方法允許servlet確定在當前請求之前的會話的最後訪問時間。

寫分佈式應用的開發人員應該意識到容器可能運行在多個Java虛擬機中,開發人員不能依賴靜態變量存儲應用狀態。應該用企業Bean或數據庫存儲這種狀態。

36.web應用中,使用註解的類僅當它們位於WEB-INF/classes目錄中,或它們被打包到位於應用的WEB-INF/lib中的jar文件中時它們的註解纔將被處理。

Web應用部署描述符的web-app元素包含一個新的"metadata-complete"屬性。"metadata-complete"屬性定義了web描述符是否是完整的,或是否應該在部署時檢查jar包中的類文件和web fragments。如果“metadata-complete”設置爲"true",部署工具必須忽略存在於應用類文件中的所有指定部署信息的servlet註解和web fragments。如果metadata-complete屬性沒有指定或設置爲false,部署工具必須檢查應用的類文件的主鍵,並掃描web fragments

@WebServlet該註解用於在Web應用中定義Servlet組件。該註解在一個類上指定幷包含聲明Servlet的元數據。必須指定註解的urlPatternsvalue屬性。所有其他屬性是可選的默認設置。當註解上唯一屬性是url Patterns時推薦使用value且當也有使用其他屬性時使用urlPatterns屬性。在同一註解上同時使用valueurlPatterns屬性是非法的。如果沒有指定Servlet名字則默認是全限定類名。被註解的Servlet必須指定至少一個url模式進行部署。如果同一個Servlet類以不同的名字聲明在部署描述符中,必須實例化一個新的Servlet實例。如果使用不同名字添加的同一個Servlet類使用編程式添加和配置Servlet”的編程式API添加到ServletContext,使用@WebServlet註解聲明的屬性值必須被忽略,必須創建一個指定名字的Servlet的新的實例。

@WebServlet註解的類必須繼承javax.servlet.http.HttpServlet類。

37.@WebFilter用於在Web應用中定義Filter。該註解在一個類上指定且包含聲明過濾器的元數據。如果沒有指定Filter名字則默認是全限定類名。註解的urlPatterns屬性,servletNames屬性或value屬性必須被指定。當註解上唯一屬性是url模式時推薦使用value且當有使用其他屬性時使用urlPatterns屬性。在同一註解上同事使用valueurlPatterns屬性是非法的。

@WebFilter註解的類必須實現javax.servlet.Filter

@WebInitParam用於指定必須傳遞到ServletFilter的任何初始化參數。它是WebServletWebFilter註解的一個屬性。

@WebListener用來獲得特定web應用上下文中的各種操作時間的監聽器。

@MultipartConfig該註解當指定在Servlet上時,表示請求原文是mime/multipart類型。相應servletHttpServletRequest對象必須使用getPartsgetPart方法遍歷各個mime附件以獲取mime附件。javax.servlet.annotation.MultipartConfiglocation屬性和<multipart-config><location>元素被解析爲一個絕對路徑且默認爲javax.servlet.context.tempdir。如果指定了相對地址,它將是相對於tempdit位置。絕對路徑與相對路徑的測試必須使用java.io.File.isAbsolute

當使用註解時,從WEB-INF/classesWEB-INF/lib中的不同框架jar/類加載監聽器、Servlet的順序是沒有指定的。如果順序是很重要的,那麼請看web.xml模塊部分和後面的web.xmlweb-fragment.xml順序部分。順序僅能在部署描述符中指定。

38.web模塊部署描述符片段(web fragment)是web.xml的部分或全部,可以在一個類庫或框架jar包的META-INF目錄指定和包括。在WEB-INF/lib目錄中的普通的老的jar文件即使沒有web-fragment.xml也可能被認爲是一個fragment

由於規範允許應用配置由多個配置文件組成(web.xmlweb-fragment.xml)的資源,從應用中多個不同的位置發現和加載,順序問題必須被解決。

web-fragment.xml可以有一個javaee:java-identifierType類型的頂級<name>元素,且在一個web-fragment.xml中僅能有一個<name>元素。如果存在一個<name>元素,它必須考慮用於artifact順序(除非出現重複名異常)

39.ServletContainerInitializer和編程時註冊特性可以在ServletJSP容器之間提供一個清晰的職責分離,通過由Servlet容器只負責解析web.xmlweb-fragment.xml資源,而解析標籤類庫描述符(TLD)資源委託給JSP容器。

在此之前,web容器必須掃描TLD資源尋找任何Listener聲明。使用Servlet3.0和後續版本後,該職責可以委託給JSP容器。JSP容器是內嵌到一個Servlet3.0兼容的Servlet容器中,可以提供它自己的ServletContainerInitializer實現,搜索傳遞到它的onStartup方法的ServletContext參數尋找任何TLD資源,掃描這些資源尋找Listener聲明,並向ServletContext註冊相關的Listener

40.構建Web應用時,把請求轉發給另一個servlet處理、或在response中包含另一個servlet的輸出通常是很有用的。RequestDispatch接口提供了一種機制來實現這種功能。當請求啓用異步處理時,AsyncContext允許用戶將這個請求轉發到servlet容器。

實現了RequestDispatcher接口的對象,可以從ServletContext中的下面方法得到:

1getRequestDispatcher 需要一個String類型的參數描述在ServletContext作用域內的路徑。這個路徑必須是相對於ServletContext的根路徑,或以'/'開頭,或者爲空。該方法根據這個路徑使用servlet路徑規則來查找servlet,或者把它包裝成RequestDispatcher對象並返回。如果基於給定的路徑沒有找到相應的servlet,那麼返回這個路徑內容提供的RequestDispatcher

2getNamedDispatcher方法使用一個ServletContext知道的servlet名稱作爲參數。如果找到一個servlet,則把它包裝成RequestDispatcher對象,並返回該對象。如果沒有與給定名字相關的servlet,則該方法必須返回null

ServletContextServletRequest中創建RequestDispatcher對象的方法使用的路徑信息中允許附加可選的查詢字符串信息。

要使用請求調度器,servlet可調用RequestDispatcher接口的includeforward方法。這些方法的參數既可以是javax.servlet.Servlet接口的service方法傳來的requestresponse對象實例,也可以是requestresponse包裝器的子類對象實例。對於後者,包裝器實例必須包裝容器傳遞到service方法中的requestresponse對象。

41.RequestDispatcher接口的include方法可能隨時被調用。Include方法的目標servlet能夠訪問request對象的各個方法,但是調用response對象的方法會受到更多限制。它只能把信息寫到response對象的ServletOutputStreamWriter中,或提交在最後寫保留在response緩衝區中的內容,或通過顯式地調用ServletResponse接口的flushBuffer方法。它不能設置響應頭部信息或調用任何影響響應頭部信息的方法,HttpServletRequest.getSession()HttpServletRequest.getSession(boolean)方法除外。

如果默認的servletRequestDispatch.include()的目標servlet,而請求的資源不存在,那麼默認的servlet必須拋出FileNotFoundException異常。如果這個異常沒有被捕獲和處理,以及響應還未提交,則響應狀態碼必須被設置爲500

42.RequestDispatcher接口的forward方法,只有在沒有輸出提交到客戶端時,通過正在被調用的servlet調用。如果response緩衝區中存在尚未提交的輸出數據,這些數據內容必須在目標servletservice方法調用前清除。如果response已經提交,必須拋出一個IllegalStateException異常。

request對象暴露給目標servlet的路徑元素(path elements)必須反映獲得RequestDispatcher使用的路徑。

唯一例外的是,如果RequestDispatcher是通過getNamedDispatcher方法獲得。這種情況下,request對象的路徑元素必須反映這些原始請求。

RequestDispatcher接口的forward方法無異常返回前,響應的內容必須被髮送和提交,且由Servlet容器關閉,除非請求處於異步模式。如果RequestDispatcher.forward()的目標發生錯誤,異常信息或傳回所有調用它經過的過濾器和servlet,且最終傳回給容器。

43.如果請求分發的目標servlet拋出運行時異常或受檢查異常ServletExceptionIOException,異常應該傳播到調用的servlet。所有其它的異常都應該包裝成ServletException,異常的根本原因設置成原來的異常,因爲它不應該被傳播。

44.實現了AsyncContext接口的對象可從ServletRequest的一個startAsync方法中獲得,一旦有了AsyncContext對象,你就能夠使用它的complete()方法來完成請求處理,或使用下面描述的轉發方法。

45.可以使用AsyncCont中下面的方法來轉發請求:

1dispatch(path) 該方法的String參數描述一個在ServletContext作用域中的路徑。這個路徑必須是相對於ServletContext的根路徑並以'/'開頭。

2dispatch(servletContext,path)  該方法的String參數描述一個在ServletContext作用域中的路徑。這個路徑必須是相對於ServletContext的根路徑並以'/'開頭。

3dispatch() 這個方法沒有參數,它使用原來的URI路徑。如果AsyncContext已經通過startAsync(ServletRequest,ServletResponse)初始化,且傳遞過來的requestHttpServletRequest的實例,那麼這個請求分發到HttpServletRequest.getRequestURI()返回的URI

AsyncContext接口中的dispatch方法可被等待異步事件發生的應用程序調用。如果AsyncContext已經調用了complete方法,必須拋出IllegalStateException異常。所有不同的dispatch方法會立即返回並且不會提交response

request對象暴露給目標servlet的路徑元素必須反映AsyncContext.dispatch中指定的路徑。

46.一個Web應用程序以結構化的目錄層次結構存在。層次結構的根目錄作爲文件的歸檔目錄,這些文件是應用的一部分。由於應用的上下文路徑確定了Web應用內容的URL命名空間,Web容器必須拒絕Web應用定義的上下文路徑,因爲可能這個URL命名空間中導致潛在的衝突。

應用程序層次結構中存在一個名爲“WEB-INF”的特殊目錄。這個目錄包含了與應用程序相關的所有東西,這些東西不在應用程序的歸檔目錄中。大多數WEB-INF節點都不是應用程序公共文檔樹的一部分。除了靜態資源和WEB-INF/lib目錄下打包在JAR文件中META-INF/resources目錄下的JSP文件之外,WEB-INF目錄下包含的其他任何文件都不能由容器直接提供給客戶端訪問,然而,WEB-INF目錄中的內容可以通過servlet代碼調用ServletContextgetResourcegetResourceAsStream方法來訪問,並可使用RequestDispatcher調用公開這些內容。

WEB-INF目錄中的內容有:

1/WEB-INF/web.xml部署描述文件。

2servlet和實用工具類目錄/WEB-INF/classes/。此目錄中類對應用程序類加載器必須是可見的。

3java歸檔文件區域/WEB-INF/lib/*.jar。這些文件中包括了sevletbeans,靜態資源和打包在JAR文件中的JSP文件,以及其他對Web應用程序有用的使用工具類。Web應用程序的加載器必須能夠從這些歸檔文件中加載類。

Web應用程序類加載器必須先從WEB-INF/classes目錄下加載類,然後從WEB-INF/lib目錄下的JAR庫中加載。此外,除了靜態資源打包在JAR文件中的情況外,任何來自客戶端的請求訪問WEB-INF/目錄中的資源必須返回一個SC_NOT-FOUND(404)的響應。

可以使用標準的Java歸檔工具把Web應用程序打包並簽名到一個Web存檔格式(WAR)文件中。

當打包成這種形式時,將生成一個META-INF目錄,其中包含了對java歸檔工具有用的信息。儘管這個目錄的內容可以通過servlet代碼調用ServletContextgetResourcegetResourceAsStream方法來訪問,容器也不能把這個目錄當做內容來響應客戶端請求。此外,任何請求訪問META-INF目錄中的資源必須返回一個SC_NOT_FOUND(404)的響應。

47.容器用於加載WAR文件中servlet的類加載器必須允許開發人員使用getResource加載遵循正常JavaSE語義的WAR文件的JAR包中包含的任何資源。和Java EE許可協議中描述的一樣,不屬於Java EE產品的servlet容器不應該允許應用程序覆蓋Java SE平臺中的類。

一個類加載器的實現必須保證對部署到容器的每個web應用,調用Thread.currentThread.getContextClassLoader()返回一個實現了本節規定的約定的ClassLoader實例。此外,部署的每個Web應用程序的ClassLoader實例必須是一個單獨的實例。容器必須在任何回調(包括監聽器回調)到Web應用程序之前設置上面描述的線程上下文ClassLoader,一旦回調返回,需要把它設置成原來的ClassLoader

48.在發生錯誤時,Web應用程序必須能夠詳細說明,應用程序中的其他資源被用來提供錯誤響應的內容主題。

49.如果Web容器接收到一個有效的局部請求,Web容器必須檢查部署描述文件中定義的歡迎文件列表。歡迎文件列表是一個沒有尾隨或前導的局部URL有序列表。Web服務器必須把部署描述文件中按指定順序的每個歡迎文件添加到局部請求,並檢查WAR文件中的靜態資源是否映射到請求URIWeb服務器必須再把部署描述文件中指定順序的每個歡迎文件添加到局部請求,並檢查servlet是否映射到請求URIWeb容器必須將請求到WAR文件中第一個匹配的資源。容器可使用轉發、重定向、或容器指定的機制將請求發送到歡迎資源,這與直接請求沒有什麼區別。

50.當一個Web應用程序部署到容器中,在Web應用程序開始處理客戶端請求之前,必須按照下述步驟順序執行:

1)實例化部署描述文件中<listener>元素表示的每個事件監聽器的一個實例。

2)對於已實例化的實現了ServletContextListener接口的監聽器實例,調用contextInitialized()方法。

3)實例化部署描述文件中<filter>元素標識的每個過濾器的一個實例,並調用每個過濾器實例的init()方法。

4)包含<load-on-starup>元素的<servlet>元素,根據load-on-startup元素值定義的順序爲每個servlet實例化一個實例,並調用每個servlet實例的init()方法。

51.如果Web應用不包含任何servlet、過濾器或監聽器組件或使用註解聲明相同的,那麼可以不需要web.xml文件。換句話說,只包含靜態文件或JSP頁面的應用程序不需要一個web.xml的存在。

52.Servlet事件監聽器支持在ServletContextHttpSessionServletRequest狀態改變時進行事件通知。Servlet上下文監聽器是用來管理應用的資源或JVM級別持有的狀態。HTTP會話監聽器是用來管理從相同客戶端或用戶進入web應用的一系列請求管理的狀態或資源。Servlet請求監聽器是用來管理整個Servlet請求週期的狀態。一步監聽器用來管理異步事件。如超時和完成異步處理。

可以有多個監聽器類監聽每一個事件類型,且開發人員可以爲每一個事件類型指定容器調用監聽器bean的順序。

監聽器類在Web應用部署描述符中使用listener元素聲明。它們根據類名列出的順序就是它們被調用的順序。與其他監聽器不同,AsyncListener類型和監聽器可能僅通過編程式註冊(使用一個ServletRequest)。

Web容器創建每一個監聽器類的一個實例,並在應用處理第一個請求之前爲事件通知註冊它。

在分佈式Web容器中,HttpSession實例被限定到特定的JVM服務會話請求,且ServletContext對象被限定到Web容器所在的JVM。分佈式容器不需要傳播Servlet上下文事件或HttpSession事件到其他JVM。監聽器類實例被限定到每個JVM的每個部署描述符聲明一個。

53.在收到客戶端請求時,web容器確定轉發到哪一個Web應用。選擇的Web應用必須具有最長的上下文路徑匹配請求URL的開始。當映射到Servlet時,URL匹配的一部分是上下文。

用於映射到Servlet的路徑是請求對象的請求URL減去上下文和路徑參數部分。下面的URL路徑映射規則按順序使用。使用第一個匹配成功的且不會進一步嘗試匹配:

1)容器將嘗試找到一個請求路徑到servlet路徑的精確匹配。成功匹配則選擇該servlet

2)容器將遞歸地嘗試匹配最長路徑前綴。這是通過一次一個目錄的遍歷路徑樹完成的,使用'/'字符作爲路徑分隔符。最長匹配確定選擇的servlet

3)如果URL最後一部分包含一個擴展名(如.jsp),servlet容器將視圖匹配爲擴展名處理請求的Servlet。擴展名定義在最後一部分的最後一個'.'字符之後。

4)如果前三個規則都沒有產生一個servlet匹配,容器將視圖爲請求資源提供相關的內容。如果定義中定義了一個‘default’Servlet,它將被使用。

容器必須使用區分大小寫字符串的比較匹配。

web應用部署描述符中,以下語法用於定義映射:

1)以'/'字符開始,以'/*'後綴結尾的字符串用於路徑匹配。

2'*.'開始的字符串用於擴展名映射。

3)空字符串""是一個特殊的URL模式,其精確映射到應用的上下文根,即http://host:port/<context-root>/請求形式。在這種情況下,路徑信息是'/'servlet路徑和上下文路徑是空字符串("");

4)只包含'/'字符的字符串表示應用的"default"servlet。在這種情況下,servlet路徑請求時請求URL減去上下文路徑,且路徑信息時null.

5)所有其他字符串僅用於精確匹配。

如果容器有一個內部的JSP容器,*.jsp擴展名映射到它,允許執行JSP頁面的要求。該映射被稱爲隱式映射。如果Web應用定義了一個*.jsp映射,它的優先級高於隱式映射。

54.聲明式安全是指以在應用外部的形式表達應用的安全模型需求,包括角色、訪問控制和認證需求。部署描述符是web應用中的聲明式安全的主要手段。

編程式安全包括以下HttpServletRequest接口的方法:

1authenticate 允許應用由容器發起在一個不受約束的請求上下文內的來訪者請求認證。

2login 允許應用執行用戶名和密碼收集(作爲一種Form-Based Login的替代)。

3logout 提供用於應用重置來訪者的請求身份。

4getRemoteUser 又涌起返回與該請求相關的遠程用戶(即來訪者)的名字。

5isUserInRole 確定是否與該請求相關的遠程用戶(即來訪者)在一個特定的安全角色中。

6getUserPrincipal 確定遠程用戶(即來訪者)的Principal名稱並返回一個與遠程用戶相關的java.security.Principal對象。調用getUserPrincipal返回的PrincipalgetName方法返回遠程用戶的名字。這些API允許Servlet基於獲取的信息做一些業務邏輯決策。

55.@ServletSecurity提供了用於定義訪問控制約束的另一種機制,相當於那些通過在便攜式部署描述符中聲明式或通過ServletRegistration接口的serServletSecurity方法編程式表示。Servlet容器必須支持在實現javax.servlet.Servlet接口的類(和它的子類)上使用@ServletSecurity註解。

@HttpConstraint註解用在@ServletSecurity中標示應用到所有HTTP協議方法的安全約束,且HTTP協議方法對應的@HttpMethodConstraint沒有出現在@ServletSecurity註解中。

@HttpMethodConstraint註解用在@ServletSecurity註解中表示在特定HTTP協議消息上的安全約束。

定義在便攜式部署描述符中的security-constraint元素用於對所有出現在該約束中的url-pattern授權。

當在便攜式部署描述符中的一個security-constraint包含一個url-pattern,其精確匹配一個使用@ServletSecurity註解的模式映射到的類,該註解必須在由容器在該模式上強制實施的約束上沒有效果。

@ServletSecurity註解用於定義一個方法無關的@HttpConstraint,且緊跟着一個包含零個或多個@HttpMethodConstaint規格的列表。方法無關的約束應用到那些沒有定義HTTP特定方法約束的所有HTTP方法。

當沒有包含@HttpMethodConstraint元素,@ServletSecurity註解相當於包含一個web-resource-collection的單個security-constraint元素,且web-resource-collection不包含http-method元素,因此涉及到所有HTTP方法。

ServletContextListener內的setServletSecurity方法用於定義應用到ServletRegistration定義的映射的安全約束。

Collection<String> setServletSecurity(ServletSecurityElement arg);

serServletSecurity方法返回一組URL pattern(可能空),其已是便攜式部署描述符中的security-constraint元素的精確目標(因此,調用是不影響的)。

如果ServletContext中得到的ServletRegistration已經被初始化了,該方法拋出IllegalStateException

當便攜式部署描述符中的security-constraint包含一個url-pattern其精確匹配ServletRegistration映射的pattern,調用ServletRegistrationsetServletSecurity必須對Servlet容器對pattern實施的約束沒有任何影響。

56.安全角色是由應用開發人員或裝配人員定義的邏輯用戶分組。當部署了應用,由部署人員映射覺得到運行時環境的principal或組。

Servlet容器根據principal的安全屬性爲與進入請求相關的principal實施聲明式或編程式安全。

這可能以如下任一方式發生:

1)部署人員以及映射一個安全覺得到運行環境中的一個用戶組。調用的principal所屬的用戶組取自其安全屬性。僅當principal所屬的用戶組由部署人員已經映射了安全角色,principal是在安全角色中。

2)部署人員已經映射安全角色到安全策略域中的principal名字。在這種情況下,調用的principal的名字取自其安全屬性。僅當principal名字與安全角色一映射到的principal名字一樣時,principal是在安全角色中。

57.web客戶端可以使用一下機制之一向web服務器認證用戶身份:

1HTTP基本認證(HTTP Basic Authentication

HTTP基本認證基於用戶名和密碼,是HTTP1.0規範中定義的認證機制。Web服務器請求web客戶端認證用戶。作爲請求的一部分,web服務器傳遞realm(字符串)給要被認證的用戶。Web客戶端獲取用戶的用戶名和密碼並傳給web服務器。Web服務器在指定的realm認證用戶。

基本認證是不安全的認證協議。用戶密碼以簡單的base64編碼發送,且未認證目標服務器。

2HTTP摘要認證(HTTP Digest Authentication

HTTP基本認證類似,HTTP摘要認證也是基於用戶名和密碼認證的用戶,但不像HTTP基本認證,HTTP摘要認證不再網絡上發送用戶密碼。在HTTP摘要認證中,客戶端發送單向散列的密碼(和額外的數據)。儘管密碼不在線路上發生,HTTP摘要認證需要對認證容器可用的明文密碼等價物,以致容器可以通過計算與其的摘要驗證接收到的認證者。Servlet容器應支持HTTP_DIGEST身份認證。

3HTTPS客戶端認證(HTTPS Client Authentication

Web應用部署描述符包含登錄表單和錯誤頁麪條目。登錄界面必須包含用於輸入用戶名和密碼的字段。這些字段必須分別命名爲j_usernamej_password

當用戶試圖訪問一個受保護的web資源,容器堅持用戶的認證。如果用戶已經通過認證則具有訪問資源的權限,請求的web資源被激活並返回一個引用。

4)基於表單的認證(Form Based Authentication

當進行一個不受保護的傳輸時,基於表單的認證受制於一些與基本驗證一樣的相同的脆弱性。

當觸發認證的請求在一個安全傳輸之上到達,或者登陸頁面受制於一個CONFIDENTIAL user-data-constraint,登錄頁面必須返回給用戶,並在安全傳輸之上提交到容器。

HttpServletRequest接口的login方法提供另一種用於應用控制它的登錄界面外觀的手段。

基於表單的登錄和基於URLsession跟蹤可以通過編程實現。基於表單的登錄應該僅被用在當sessioncookieSSL session信息維護時。

爲了進行適當的認證,登錄表單的action總是j_security_check。該限制使得不管請求什麼資源,登錄表單都能工作,且避免了要求服務器指定輸出表單的action字段。登錄表單應該在密碼錶單字段上指定autocomplete="off"

58.安全約束是一種定義web內容包含的聲明式方式。安全約束關聯授權和/或在web資源上對HTTP操作的用戶數據約束。安全約束,在部署描述符中由security-constraint表示,其包含以下元素:

1web資源集合(部署描述符中的web-resource-collection

2)授權約束(部署描述符中的auth-constraint

3)用戶數據約束(部署描述符中的user-data-constraint

HTTP操作和網絡資源的安全約束應用(即受限的請求)根據一個或多個web資源集合識別。Web資源集合包含以下元素:

1URL模式(部署描述符中的url-pattern

2HTTP methods(部署描述符中的http-methodhttp-method-omisssion元素)

授權約束規定認證和命名執行守約束請求的被許可的授權角色的要求。用戶必須至少是許可執行受約束請求的命名角色中的一個成員。

特殊角色名“*”是定義在部署描述符中的所有角色名的一種簡寫。

特殊角色名“**”是一種用於任何授權的用戶不受約束的角色的速記法。它表示任何授權的用戶,不受約束的角色,被授權允許執行約束的請求。沒有指定角色的授權約束表示在任何情況下不允許訪問受約束請求。

授權約束包含以下元素:

1role name(部署描述符中的role-name

用戶數據約束規定了在受保護的傳輸層連接之上接收約束的請求的要求,需要包含的強度由傳輸保障的值定義。INTEGRAL類型的傳輸保障用於規定內容完整性要求,且傳輸保障CONFIDENTIAL用於規定保密性要求的。傳輸保障“NONE”表示當容器通過任何包括不受保護的連接接收到請求時,必須接收此受約束的請求。容器可能在響應中搶救一個收報紙的傳輸保障(confidential transport guarantee)爲INTEGRAL值。用戶數據約束包括如下元素:

2transport guarantee(部署描述符中的transport-guarantee

如果沒有授權約束應用到請求,容器必須接受請求,而不要求用戶身份認證。如果沒有用戶數據約束應用到請求,當容器通過任何包括不受保護的連接接受到請求時,必須接收此請求。

59.url-patternHTTP方法以組合方式(即,在web-resource-collection中)出現在多個安全約束中,該約束(在模式和方法上的)是通過合併單個約束定義的。以相同的模式和方法出現在組合約束規則如下所示:

授權約束組合,其明確指定角色或通過"*"隱式指定角色,可產生單個約束的合併的角色名稱作爲許可的角色。一個命名覺得“**”的授權約束命名的或隱式的角色組合以允許任何授權的用戶不受約束的角色。不包含授權約束的安全約束將與明確指定角色的或隱式指定角色的允許未授權訪問的安全約束合併。授權約束的一個特殊情況是其沒有指定角色,將與任何其他約束合併並覆蓋它們的作用。這導致訪問被阻止。

60.1web-app元素是一個Web應用程序的根部署描述符。此元素包含下列元素。這個元素有一個必須的屬性version來指定部署描述符符合哪個版本的模式。此元素的所有子元素可以是任意的順序。

2description元素提供了父元素的文本描述。

3displ-name元素包含一個簡短的名稱,目的是通過攻擊顯示,顯示名稱不必是唯一的。

4icon元素包含small-iconlarge-icon元素,爲大型和小型GIFJPEG圖標圖片指定文件名,用於在GUI工具中標示父元素。

5distributable元素表示設定該Web應用程序適合部署到一個分佈式的servlet容器中。

6context-param元素包含了Web應用程序的servlet上下文初始化參數的聲明。

7filter元素聲明瞭Web應用程序中的過濾器。該過濾器映射到一個servletfilter-mapping元素中的一個URL模式,使用filter-name的值來引用。過濾器在運行時可以通過FilterConfig接口中訪問部署描述文件中聲明的初始化參數。filter-name元素是過濾器的邏輯名稱。他在Web應用程序中必須是唯一的。filter-name元素的元素內容不能爲空。filter-class是過濾器的完全限定類名。init-param元素包含的名值對作爲此過濾器的初始化參數。當指定可選的async-supported元素時,表示該過濾器支持異步請求處理。

8)容器使用filter-mapping決定哪個過濾器以什麼樣的順序應用到請求。filter-name的值必須是部署描述文件中聲明的過濾器中的一個。匹配的請求可以被指定爲url-patternservlet-name

9listener表示應用程序監聽器bean的部署屬性。子元素listener-class聲明應用程序中的一個類必須註冊爲Web應用程序監聽器bean。它的值是監聽器類的完全限定類名。

10servlet元素用於聲明一個servlet。它包含一個servlet的聲明性數據。jsp-file元素包含到以"/"開頭的Web應用程序中一個JSP文件的完全路徑。如果制定了jsp-file並且存在load-on-start元素,那麼JSP應該被預編譯和加載。servlet-name元素包含了servlet的規範名稱。在Web應用程序中每個servlet的名稱是唯一的。servlet-name元素的內容不能爲空。servlet-class包含了servlet的完全類限定麼。run-as元素指定用作一個組件執行的標識。它包含一個可選的description,和一個由role-name元素指定安全角色。load-on-startup元素表示該servlet應該被加載的順序。如果該值是一個負整數,或不在該元素,容器自由選擇什麼時候加載這個servlet。如果該值是一個正整數或0,當應用部署後容器必須加載和初始化這個servlet。容器必須保證較小整數標記的servlet在較大整數標記的servlet之前加載。容器可以選擇具有相同load-on-startup值的servlet的加載順序。security-role-ref元素聲明組件或部署組件的代碼中的安全角色引用。它由一個可選的description,在代碼中使用的安全角色名稱(role-name),以及一個可選的到一個安全角色(role-link)的鏈接組成。如果沒有指定安全角色,部署器必須選擇一個合適的安全角色。當指定了可選的async-support元素,指示的servlet可支持異步請求處理。如果一個servlet支持文件上傳功能和mime-multipart請求處理,通過描述文件中的multipart-config元素能夠提供相同的配置。multipart-config元素可用於指定文件存儲的位置,上傳文件大小的最大值,最大請求大小和文件將寫入磁盤之後的大小閾值。

11servlet-mapping元素定義了servletURL模式之間的映射。

12session-config元素定義了該Web應用程序的會話參數。子元素session-timeout定義了該Web應用程序中創建的所有會話的默認超時時間間隔。指定的超時時間必須使用分鐘數表示。如果超時時間小於或等於0,容器將確保會話的默認行爲永遠不會超時。如果沒有指定這個元素。容器必須設置它的缺省超時期限。

13mime-mapping定義了擴展名和MIME類型直接的映射。extension元素包含一個字符串描述的擴展名。

14welcome-file-list元素包含了一個有序的歡迎文件列表。子元素welcome-file包含一個用作缺省歡迎文件的文件名。

15error-page包含一個錯誤代碼或異常類型到Web應用程序中資源的路徑之間的映射。不過,error-codeexception-type元素可以省略來指定一個默認的錯誤頁面。子元素exception-type包含了一個Java異常類型的完全限定名稱。子元素location包含了web應用程序中相對於web應用程序幹目錄的資源位置。location的值必須以'/'開頭。

16jsp-config用來提供Web應用程序中的JSP文件的全局配置信息。它有兩個子元素,taglibjsp-property-grouptaglib元素可用來爲Web應用程序中的JSP頁面使用的標籤庫提供信息。

17security-constraint元素用於關聯安全約束和一個或多個Web資源集合。子元素web-resource-collection確定安全約束應用到哪一些Web應用程序中資源的子集和這些資源的HTTP方法。auth-constraint表示擁護角色應該允許訪問此資源集合。這裏使用的role-name必須與該Web應用程序定義的其中一個security-role元素的role-name對應,或是指定的保留role-name“*”對應。這是一個表示web應用程序中的所有角色的緊湊語法。如果“*”和角色名都出現了,容器會將此解析爲所有角色。如果沒有定義覺得,不允許任何用戶訪問由包含security-constraint所描述的Web應用程序的部分。當容器確定訪問時匹配角色名稱是區分大小寫的。user-data-constraint表示客戶端和容器之間的通信數據如何受到子元素transport-guarantee的保護。transport-guarantee的合法值是NONEINTEGRALCONFIDENTIAL之一。

18login-config用於配置應該使用的驗證方法,可用於此應用程序的領域名,以及表單登錄機制所需要的屬性。子元素auth-methodWeb應用程序配置驗證機制。該元素的內容必須是BASICDIGESTFORMCLIENT-CERTvendor-specific驗證模式。realm-name表示爲Web應用程序選擇用於驗證模式的領域名。form-login-config指定應該用於基於表單登錄的登錄和錯誤頁面。如果不使用基於表單的登錄方式,這些元素將被忽略。

19security-role定義了一個安全角色。子元素role-name指定安全角色的名稱。該名稱必須符合NMTOKEN的詞法規則。

20env-entry聲明瞭一個應用程序的環境入口。子元素env-entry-name包含部署組件環境入口的名稱。這個名稱是一個相對於java:comp/env上下文的JNDI名稱。在部署組件中該名稱必須是唯一的。env-entry-type包含了應用程序代碼所期望的環境入口值的Java類型完全限定名。子元素env-entry-value指定部署組件的環境入口值。該值必須是一個String,對指定的使用一個Stringjava.lang.Character類型作爲參數的構造器有效。可選的injection-target元素用來定義把指定的資源注入到字段或JavaBean屬性。injection-target指定了類中應該被注入資源的類和名稱。injection-target-class制定了注入目標的完全限定類名稱、injection-target-name制定了指定雷中的目標。首先把查找目標作爲一個JavaBean屬性名稱。如果沒有找到,則把查找目標作爲一個字段名。在類初始化期間通過調用目標屬性的set方法或給名稱字段設置一個值將指定的資源注入到目標。如果環境入口指定了一個injection-target,那麼env-entry-type可以省略或必須與注入目標的類型匹配。如果沒有指定injection-target,那麼需要指定env-entry-type

21ejb-ref聲明瞭一個對企業beanhome應用。ejb-ref-name制定了引用企業bean的部署組件代碼中使用的名稱。ejb-ref-type是引用的企業bean期望的類型,它可以是EntitySessionhome定義了引用的企業beanhome接口的完全限定名稱。remote定義了引用的企業beanremote接口的完全限定名稱。ejb-link指定了連接到企業bean的一個EJB應用。injection-target元素可以用於定義指定的企業bean注入到一個組件的字段或屬性。

22ejb-local-ref聲明瞭對企業bean的本地home引用。local-home定義了企業bean的本地home接口的完全限定名稱。local定義了企業bean的本地接口的完全限定名稱。

23service-ref聲明瞭一個對Web service的引用。service-ref-name聲明瞭用於查找Web service模塊組件的邏輯名稱。建議所有service的引用名稱以/service/開頭。service-interface定義了客戶端依賴的JAX-WS Service接口的完全限定類名稱。在大多數情況下,這個值是javax.xml.rpc.Service。也可以指定一個JAX-WS生成的服務接口類。wsdl-file元素包含了WSDL文件的URI位置。這個位置相對於模塊根目錄。jaxrpc-mapping-file包含了描述應用程序使用的Java接口和wsdl-file中的WSDL描述之間的JAX-WS映射的文件名。這個文件名是一個模塊文件中的相對路徑。

24resource-ref元素包含了部署組件對外部資源的引用聲明。res-ref-name指定了一個資源管理器連接工程引用的名稱。這個名稱是一個相對於java:com/env上下文的JNDI名稱。在部署文件中這個名稱必須是唯一的。res-type元素指定數據源的類型。該類型是一個希望由數據源實現的Java語言類或接口的完全限定名。res-auth指定部署組件代碼是否以編程方式註冊到資源管理器,或容器是否將代表的部署組件註冊到資源管理器。如果是第二種情況,容器使用部署器提供的註冊信息。res-sharing-scope指定了通過給定的資源管理器連接工廠引用獲取的連接是否可以共享。如果制定了這個值,它必須是ShareableUnshareable。可選的injection-target元素用於定義把指定的資源注入到字段或JavaBean屬性。

25resource-env-ref包含了部署組件和對部署組件環境中的資源有關的關聯對象的引用。resource-env-ref-name指定了資源環境引用的名稱。它的值是部署組件代碼中使用的環境入口名稱,它是一個相對於java:comp/env上下文的JNDI名稱,並且在部署組件中必須唯一的。resource-env-ref-type制定了資源環境引用的類型。它是一個Java語言類或接口的完全限定名。可選的injection-target元素用於定義把指定的資源注入到字段或JavaBean屬性。必須提供resource-env-ref-type除非指定了注入目標,在這種情況下,將使用目標的類型。如果兩者都指定,該類型必須與注入目標的類型兼容。

26message-destination-ref元素包含了部署組件和對部署組件環境中的資源有關的目標的引用聲明。message-destination-ref-name元素制定了一個目標引用的名稱,它的值是部署組件代碼中使用的環境入口名稱。

27message-destination指定消息的目標。這個元素所描述的邏輯目標由部署映射到物理目標。message-destination-name元素指定了消息目標的名稱。該名稱在部署文件的消息目標名稱中必須是唯一的。

28local-encoding-mapping-list包含了語言環境和編碼直接的映射。由子元素locale-encoding-mapping指定。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章