性格決定命運(yùn),氣度影響格局
          posts - 20, comments - 18, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          Servlet2.3規(guī)范 轉(zhuǎn)載

          Posted on 2007-08-18 22:22 尚愛軍 閱讀(691) 評論(0)  編輯  收藏

          Servlet2.3規(guī)范
          第一章:
          servlet2.3規(guī)范用到了一下的一些規(guī)范:J2EE、JSP1.1、JNDI
          在14章中講述了規(guī)范中的所有的classes類或接口(改文中不講述)。對開發(fā)者而言以下的有些相關(guān)的協(xié)議:URI、URL、HTTP/1.0、MIME、HTCPCP/1.0、XML
          1.1 什么是servlet?
          servlet是一個(gè)基于java技術(shù)的web組件,該組件被容器管理,能被編譯成字節(jié)碼被web服務(wù)調(diào)用;容器也被稱之為引擎,是支持servlet功能的web服務(wù)的擴(kuò)展。servlet之間的通信是通過客戶端請求被引擎執(zhí)行成request/response對象進(jìn)行的。
          1.2 什么是servlet引擎?
          servlet引擎是web服務(wù)器或應(yīng)用服務(wù)器的一部分,服務(wù)器能夠支持網(wǎng)絡(luò)的請求/響應(yīng),基于請求解析MIME,基于響應(yīng)格式化MIME。servlet引擎是一個(gè)servlet容器,也掌管著servlet的生命周期。
          所有的servlet引擎都必須支持HTTP的請求/響應(yīng)模式,但HTTPS的請求/響應(yīng)模式也是被支持的。HTTP的版本最小要HTTP/1.0,最好是HTTP/1.1。servlet引擎也具有安全和權(quán)限的一些特性,這些特性其服務(wù)器應(yīng)提供。
          1.3 例子
          一個(gè)典型的事件執(zhí)行的順序是:
          1)       客戶端向web服務(wù)器發(fā)起一個(gè)HTTP請求
          2)       HTTP請求被web服務(wù)器接受,并移交給servlet引擎,servlet引擎可以在主機(jī)的同一個(gè)進(jìn)程、不同的進(jìn)程或其他的web服務(wù)主機(jī)的進(jìn)程中啟動(dòng)。
          3)       servlet引擎根據(jù)servlet的配置檔確定調(diào)用的servlet,并把request對象、response對象傳給它。
          4)       4.servlet通過request對象知道客戶端的使用者是誰,客戶的請求信息是什么和其他的一些信息。servlet處理完請求后把要返回的信息放入response對象返回到客戶端
          5) 一旦servlet完成了請求的處理,servlet引擎就會刷新response,把控制權(quán)返回給web服務(wù)器
          1.4與其它技術(shù)的比較
          與其它服務(wù)相比servlet有以下的一些優(yōu)點(diǎn)
          1)       運(yùn)行速度上比CGI快,因?yàn)槭褂昧硕嗑€程
          2)       servlet使用了標(biāo)準(zhǔn)的api,可被許多web服務(wù)支持
          3)       與系統(tǒng)無關(guān)性,一次編譯多次使用
          第二章
          servlet接口是servlet api核心部分,所有的servlet都是直接或間接的實(shí)現(xiàn)了這些接口。兩個(gè)最重要的servlet api 接口是GenericServlete 和 HttpServlet,更多的開發(fā)者都繼承HttpServlet去實(shí)現(xiàn)他們的servlet
          2.1 Request 包含的方法
          一個(gè)基本的servlet接口應(yīng)該定義一個(gè)方法包含客戶端的信息,每次servlet引擎把一個(gè)request發(fā)送到一個(gè)servlet事例,這個(gè)方法都要被調(diào)用。
          對于并發(fā)的請求,web應(yīng)用需要設(shè)計(jì)者設(shè)計(jì)的servlet引擎能分配多個(gè)線程執(zhí)行這個(gè)方法。
          2.1.1 HTTP 請求處理的方法
          HttpServlet是實(shí)現(xiàn)了Servlet接口的抽象類,增加了一些新的方法,這些方法在處理HTTP請求時(shí)會被service方法自動(dòng)調(diào)用,這些方法是:
          doGet 接受 HTTP 的GET請求
          doPost 接受 HTTP 的POST請求
          doPut 接受 HTTP的PUT請求
          doDelete 接受 HTTP的DELETE請求
          doHead 接受 接受 HTTP的HEAD請求
          doOptions 接受 HTTP的OPTIONS請求
          doTrace 接受 HTTP的TRACE請求
          一個(gè)開發(fā)者只會涉及到doGet和doPost方法,其它的方法是為非常熟悉HTTP的設(shè)計(jì)師準(zhǔn)備的
          2.1.2
          HTTP/1.0只定義了doGet,doHead,doPost方法,沒有定義PUT,DELETE,OPTIOONS和TRACE方法
          2.1.3
          HttpServlet接口定義了getLastModified方法
          2.2 實(shí)例數(shù)
          2.2.1
          在分布式環(huán)境中servlet引擎為每個(gè)servlet只能聲明一個(gè)實(shí)例,當(dāng)一個(gè)servlet實(shí)現(xiàn)了SingleThreadModel接口時(shí),servlet引擎可以聲明多個(gè)實(shí)例去處理請求,servlet在應(yīng)用服務(wù)的部署描述中定義發(fā)布.
          2.2.2單線程servlet
          SingleThreadModel接口保證了在同一時(shí)刻一個(gè)servlet實(shí)例的service方法只會被一個(gè)線程執(zhí)行。這對于每個(gè)請求發(fā)送給每個(gè)實(shí)例是很重要的。引擎可以從對象池中選擇,對象池可以在同一時(shí)刻保持多個(gè)實(shí)例,如HttpSession可以被多個(gè)servlet在任何時(shí)候調(diào)用包括實(shí)現(xiàn)了SingleThreadModel接口的servlet
          2.3 servlet的生命周期
               一個(gè)好的生命周期的定義應(yīng)該是servlet怎么被引入了,怎么實(shí)例化的,怎么初始化的?當(dāng)請求從客戶端來的時(shí)候,是怎么從服務(wù)器中取出來的,這些在javax.servlet.Servlet的接口的init,service,destroy方法中都有明確的定義。
          所有的servlet都必須實(shí)現(xiàn)GenericServlet或HttpServlet抽象類
          2.3.1 servlet的引入和實(shí)例化
          servlet引擎會可靠的引入和實(shí)例化servlet,當(dāng)servlet引擎被啟動(dòng)時(shí)servlet就被引入和實(shí)例化了,或者當(dāng)一個(gè)servlet被請求時(shí)被引擎引入和實(shí)例化。
          servlet引擎啟動(dòng)時(shí),需要裝載的類通過java的裝載類進(jìn)行裝載,被裝載的類可以在本地文件系統(tǒng)、遠(yuǎn)程文件系統(tǒng)或網(wǎng)絡(luò)服務(wù)中。在裝載完后,引擎就實(shí)例化它們。
          2.3.2 初始化
          在servlet對象實(shí)例化后,引擎必須在這個(gè)servlet接受客戶段請求之前初始化,在初始化中servlet可以讀取固定的配置信息,一些昂貴的資源如數(shù)據(jù)庫連接和一次性激活的資源,引擎通過調(diào)用servlet接口的init方法初始化。每個(gè)serlet對象都實(shí)現(xiàn)了Servlet接口和ServletConfig接口,ServletConfig接口允許servlet接受web應(yīng)用配置檔中配置的參數(shù),還向servlet中傳入了一個(gè)描述servlelt運(yùn)行環(huán)境的類(ServletContext)
          2.3.2.1 在初始化時(shí)發(fā)生錯(cuò)誤
          在初始化過程中,servlet實(shí)例能拋出UnavailableException 或ServletException異常。在這樣的情況下servlet不能被放入服務(wù)中,必須被引擎釋放,destroy方法沒有被調(diào)用。在初始化失敗后引擎可以在UnavailableException異常規(guī)定的最短無效時(shí)間后實(shí)例化新的一個(gè)實(shí)例,再初始化。
          2.3.3 request
          當(dāng)servlet初始化完成后,引擎可以使用它去處理客戶端的請求了。請求被封裝在Servletrequest類型的對象中,響應(yīng)信息被封裝在ServletResponse類型的對象中,這兩個(gè)對象以參數(shù)的形式傳給Servlet接口中的service方法。
          2.3.3.1 多線程問題
          servlet引擎可以發(fā)送并發(fā)的請求給servlet的service方法,servlet開發(fā)者必須提供足夠的線程來運(yùn)行service方法。
          對開發(fā)者來說一個(gè)可以選擇的方法是實(shí)現(xiàn)SingleThreadModel接口,以確保在同一時(shí)刻只有一個(gè)請求在service方法中。一個(gè)引擎要確保請求能夠在servlet中持續(xù)化,或維持在一個(gè)servlet實(shí)例池中,如果servlet是web應(yīng)用服務(wù)的一部分,引擎可以在一個(gè)虛擬機(jī)中擁有一個(gè)servlet實(shí)例化的池。
          對于沒有實(shí)現(xiàn)SingleThreadModel接口的servlet,如果service方法(或 doGet,doPost)被聲明為synchronized,引擎將不能用實(shí)例池的途徑,而必須持續(xù)化請求,強(qiáng)力建議開發(fā)者不能聲明synchronize service方法,這樣會嚴(yán)重影響系統(tǒng)的性能。
          2.3.3.2 request中的異常
          在處理請求時(shí)servlet可以拋出ServletException或UnavailableException異常,一個(gè)ServletException異常會在處理一個(gè)請求出現(xiàn)錯(cuò)誤時(shí)拋出,引擎將清除這個(gè)異常。當(dāng)servlet一時(shí)或永久地不能獲得一個(gè)請求時(shí)就會拋出UnavailableException異常,如果是一個(gè)永久性異常時(shí)引擎將調(diào)用它的destroy方法從服務(wù)器中消除servlet實(shí)例,如果是暫時(shí)性異常時(shí)引擎在異常期間不發(fā)送請求給servlet。如果返回SERVICE_UNAVAILABLE(503)響應(yīng),在這期間引擎將不接受任何請求,直到header中出現(xiàn)Retry-After。引擎可以不區(qū)分永久性還是暫時(shí)性的異常把所有的UnavailableException作為永久性處理。
          2.3.3.3 線程安全
          執(zhí)行request和response對象不能保證是線程安全的,意思是說他們只能在請求的線程中使用,不能被其它線程中的對象使用。
          2.3.4 結(jié)尾
          servlet實(shí)例可能被引擎保存幾毫秒或和引擎一樣的生命時(shí)間或在這兩者之間。當(dāng)引擎決定結(jié)束一個(gè)servlet時(shí),調(diào)用它的destroy方法,在destroy中釋放任何長久固定的資源。
          在引擎調(diào)用desroy方法之前,必須保證運(yùn)行在service方法中的線程都完成處理,或者超過了服務(wù)定義的執(zhí)行時(shí)間。
          一旦servlet實(shí)例的destroy方法被調(diào)用,引擎不在發(fā)送任何請求給這個(gè)實(shí)例。如果引擎再次使用這個(gè)servlet就必須再建一個(gè)這個(gè)servlet的實(shí)例。
          在destroy方法執(zhí)行完成后,引擎將釋放這個(gè)servlet實(shí)例,于是就符合垃圾回收機(jī)制的條件了。
          3.1 介紹ServletContext接口
          ServletContext接口定義了servlet運(yùn)行環(huán)境的信息。引擎提供商有義務(wù)在servlet引擎中提供一個(gè)實(shí)現(xiàn)了ServletContext接口的對象。通過這個(gè)對象servlet能夠獲得log事件,資源的URL,設(shè)置或存儲servlet之間通信的變量。ServletContext在web服務(wù)中確定了一個(gè)所有請求開始的路徑,是ServletContext的上下文路徑。
          3.2 ServletContext 接口的作用范圍
          每個(gè)web應(yīng)用配置到容器中都會產(chǎn)生一個(gè)實(shí)現(xiàn)了ServvletContext接口的實(shí)例。如果是分布式的,將會在每個(gè)java虛擬機(jī)上產(chǎn)生一個(gè)ServletContext實(shí)例。容器中默認(rèn)固有的web應(yīng)用(不是發(fā)布上來的web應(yīng)用)有一個(gè)默認(rèn)的ServletContext,在分布式中這個(gè)默認(rèn)的ServletContext只存在于一個(gè)虛擬機(jī)中,是不可分配的。
          3.3 初始化參數(shù)
          ServletContext接口的getInitParameter,getInitParameterNames方法接受部署描述文件中的初始化參數(shù),這些參數(shù)可以是的安裝信息,或網(wǎng)站管理員的mail或名字或?qū)ο到y(tǒng)的評論。
          3.4 上下文屬性
          servlet可以通過一個(gè)名稱把對象邦定到servletContext中,幫定到ServletContext中的對象都能被同一個(gè)web服務(wù)中的其它對象引用。ServletContext中的屬性方法有:
          setAttribute
          getAttribute
          getAttributeNames
          removeAttribute
          3.4.1 在分布式系統(tǒng)中 上下文的屬性
          上下文屬性是在本地的虛擬機(jī)中保存的,這防止了ServletContext屬性存在于分布式的內(nèi)存中。當(dāng)信息需要在一個(gè)分布式環(huán)境中共享的時(shí)候,信息應(yīng)該被放在session中,或存在數(shù)據(jù)庫中,或存在一個(gè)實(shí)體bean中。
          3.5 資源
          ServletContext接口提供了獲取web服務(wù)中的靜態(tài)資源的方法:
          getResource
          getResourceAsStream
          這些方法以一個(gè)“/”作為上下文的根目錄,后跟著資源路徑的路徑為參數(shù)。這些資源可以在本地服務(wù)系統(tǒng)中也可以在另個(gè)web應(yīng)用中,或在一個(gè)遠(yuǎn)程的文件系統(tǒng)中。
          這些方法不能用于去獲得一個(gè)動(dòng)態(tài)的資源,如要調(diào)用一個(gè)jsp頁面,getResource("/index.jsp")將返回index.jsp的原代碼,不能web顯示index.jsp。
          要獲得資源列表可以用getResourcePaths(String path)方法
          3.6 多主機(jī) 和 Servlet 上下文
          web服務(wù)中可能在一個(gè)IP上有多個(gè)邏輯主機(jī)的情況。在這種情況下每個(gè)邏輯主機(jī)必須有自己單獨(dú)的servlet上下文,或者設(shè)置多個(gè)servlet 上下文,但在邏輯主機(jī)中不能共享這些servlet 上下文,一個(gè)主機(jī)只能單獨(dú)使用一個(gè)。
          3.7
          引擎提供類重新裝載機(jī)制是必須的,必須確認(rèn)應(yīng)用中所有的類和接口都可以在單類裝載器中裝載;在session綁定監(jiān)聽事件中引擎會終止正在裝在的類。以前版本的裝載器,引擎創(chuàng)建一個(gè)新的裝載器裝載一個(gè)servlet或class和類裝載器裝載其他的servlet或類截然不同;這可能裝載一個(gè)未知的類或?qū)ο?,產(chǎn)生不可預(yù)知的行為。這是新的類裝載器中是應(yīng)該注意預(yù)防的問題。
          3.7.1 臨時(shí)工作目錄
          Servlet 上下文需要一個(gè)臨時(shí)存儲的目錄。servlet引擎必須為每個(gè)servlet 上下文提供一個(gè)私有臨時(shí)目錄,通過javax.servlet.context.tempdir的context屬性使目錄有效。與該屬性關(guān)聯(lián)的對象必須是java.io.File類型。
          在許多servlet引擎實(shí)現(xiàn)中提供請求可以識別的通用的機(jī)制。
          當(dāng)servlet引擎重起始不必維護(hù)臨時(shí)目錄中的內(nèi)容,但要確保臨時(shí)目錄中的該上下文內(nèi)容對于運(yùn)行在該servlet引擎中的其它web應(yīng)用中的servlet 上下文是不可見的。
          4 requeset
          request對象包含了客戶端的所有請求信息。在HTTP協(xié)議中,客戶端發(fā)送到服務(wù)端的信息都包含在請求的HTTP 頭和消息體中
          4.1 HTTP 協(xié)議的參數(shù)
           
          客戶端發(fā)送給servlet引擎的參數(shù)是包含在請求中的,引擎從客戶端請求的URI字符串中或POST數(shù)據(jù)中解析出請求的參數(shù)。參數(shù)以name-value的形式存儲的。任何一個(gè)name可以對應(yīng)多個(gè)value。在ServletRequest接口的方法中:
          getParameter
          getParameterNames
          getParameterValues
          getParameterValues方法返回關(guān)聯(lián)到一個(gè)name上的一個(gè)String對象的數(shù)組。getParameter返回name對應(yīng)的values數(shù)組中的第一個(gè)value。URI和POST體中的參數(shù)都會放入請求參數(shù)的set對象中。URI中的參數(shù)會在POST體之前被引入,如URI中的參數(shù)“a=hello”post體中的參數(shù)是a=goodbye&a=world,則參數(shù)set中的內(nèi)容是a=(hello,goodbye,world).以HTTP GET請求的參數(shù)是不隱蔽的,參數(shù)必須通過getRequestURI或getPathInfo方法獲得參數(shù)字串。
          4.1.1 參數(shù)什么時(shí)候有效
          在post form中的數(shù)據(jù)參數(shù)被放入?yún)?shù)set之前的情況是這樣的:
          1)請求是一個(gè)HTTP或一個(gè)HTTPS
          2)HTTP方法是POST
          3)內(nèi)容的類型是application/x-www-form-urlencoded
          4)初始化過的servlet從request對象中調(diào)用getParameter方法(或getParameterNames,getParameterValues)。
          Post form 中的數(shù)據(jù)符合條件的就放入?yún)?shù)set中,不符合的就放入request對象的輸入流中。
          4.2 屬性
          request的屬性是一個(gè)對象,引擎可以把API不能表達(dá)的信息放入屬性中,一個(gè)servlet也可以設(shè)置一個(gè)屬性信息用于servlet之間的通信。request對象中的屬性方法有:
          getAttribute
          getAttributeNames
          setAttribute
          一個(gè)屬性名稱只能關(guān)聯(lián)一個(gè)value。屬性名以“java.”或“javax.”為前綴的是規(guī)范保留的,類似的“sun.”“com.sun”是sun公司的保留字,這些保留的前綴是不能使用的。name建議使用統(tǒng)一的包命名規(guī)范名稱。
          4.3 頭
          servlet通過HttpServletRequest接口的方法獲得HTTP的包頭信息,這些方法是:
          getHeader
          getHeaders
          getHeaderNames
          getHeader 方法返回頭的名稱。一個(gè)名稱可以關(guān)聯(lián)多個(gè)頭信息,如果在這種情況下,getHeader方法返回第一個(gè)頭信息。
          getHeaders返回與一個(gè)名稱關(guān)聯(lián)的所有頭信息存放在Enumeration對象中。HttpServletRequest提供了一些提取頭信息的類型轉(zhuǎn)換方法,如:
          getIntHeader 把頭信息中的數(shù)據(jù)轉(zhuǎn)換成int型,如果轉(zhuǎn)換失敗會報(bào)NumberFormatException錯(cuò)誤。
          getDateHeader 把頭信息中日期的數(shù)據(jù)轉(zhuǎn)換成date型,如果轉(zhuǎn)換失敗會報(bào)IllealArgumentException錯(cuò)誤
          4.4 請求路徑
          context路徑:這路徑是和ServletContext對象關(guān)聯(lián)的,在web服務(wù)中默認(rèn)的上下文路徑是空的字符串,如果上下文路徑不是web服務(wù)的根目錄,則路徑以‘/’字符開始,但不能以‘/’結(jié)束。
          Servlet 路徑:與該請求匹配的servlet的路徑。該路徑以‘/’字符開頭,或以‘/*’開頭但后面為空字串。
          路徑信息:是請求路徑的一部分,但不是context路徑的一部分,也不是Servlet路徑的一部分,它既不為null也不是以‘/’開頭的字符串。
          上一路徑在HttpServletRequest接口中對應(yīng)的方法是:
          getContextPath
          getServletPath
          getPathInfo
          requestURI = contextPath + servletPath + pathInfo
          上下文配置的例子:
          Conteext Path           /catalog
          Servlet Mapping         Pattern:/lawn/*
                           Servlet:LawnServlet
          Servlet Mapping         Pattern:/garden/*
                                    Servlet:GardenServlet
          Servlet Mapping        Pattern:*.jsp
                                  Servlet:JSPServlet
          觀察下面的路徑
          Request path               path Elements
          /catalog/lawn/index.htm ContextPath:/catalog
                                           ServletPath:/lawn
                                           PathInfo:/index.html
          /catalog/garden/implements/
                                   ContextPath:/catalog
                                   ServletPath:/garden
                                   PathInfo:/implements/
          /catalog/help/feedback.jsp
                                   ContextPath:/catalog
                                   ServletPath:/help/feedback.jsp
                                   PathInfo:null
          4.5 路徑轉(zhuǎn)換
          在API中有兩個(gè)簡單的方法允許開發(fā)者獲得文件系統(tǒng)的路徑:
          ServletContext.getRealPath
          HttpServletRequet.getPathTranslated
          getRealPath(String aPath)方法返回本地文件系統(tǒng)的絕對路徑。getPathTranslated方法計(jì)算出請求pathInfo中的絕對路徑。
          以上的兩個(gè)方法,servlet引擎不能辨認(rèn)文件的路徑是否有效,當(dāng)web應(yīng)用調(diào)用一個(gè)不確定遠(yuǎn)程文件系統(tǒng),或數(shù)據(jù)庫路徑中的文件時(shí),會返回null
          4.6 Cookies
          HttpServletRequest接口中提供了getCookies方法返回請求中的cookies數(shù)組,在每次客戶端請求時(shí)cookies數(shù)據(jù)就從客戶端發(fā)送給服務(wù)??蛻舳朔颠€的部分cookie信息是cookie的name和cookie的value。當(dāng)cookie被送入瀏覽器時(shí),cookie的其它信息就可以設(shè)置了。
          4.7 SSL 屬性
          如果一個(gè)請求被轉(zhuǎn)給一個(gè)安全的協(xié)議,如HTTPS,這些信息必須暴露給ServletRequest接口的isSecure方法。web引擎必須把下面的信息暴露給servlet開發(fā)者:
          Attribute                 Attribute Name      javaType
               Cipher suite javax.servlet.request.cipher_suite String
          bit size of the algo-rithm javax.servlet.request.key_size Integer
          如果一個(gè)SSL證書伴隨著一個(gè)請求,servlet引擎必須把它作為一個(gè)數(shù)組對象暴露給servlet開發(fā)者,該數(shù)組中有
          java.security.cert.X509Certificate對象和放在ServletRequest屬性中的javax.servlet.request.X509Certificate對象。
          數(shù)組排列的順序是升序,在鏈中的證書的順序就是客戶端設(shè)置的順序。
          4.8 國際化
          ServletRequest接口的方法中提供了的方法:
          getLocale
          getLocales
          getLocale方法將返回客戶端將從中獲得內(nèi)容的首選的locale。要想知道更多的關(guān)于Accept-Language header 怎么解釋客戶端首選的語言的,請看14.4章
          getLocales方法返回一個(gè)Locale objects的Enumeration,從首選的locale開始遞減。
          如果客戶端沒有制定首選的locale,servlet引擎一定要提供一個(gè)默認(rèn)的locale供getLocale方法返回,getLocales方法必須包含一個(gè)默認(rèn)的locale的locale element
          4.9 Request 數(shù)據(jù)的編碼
          有許多web瀏覽器不能發(fā)送一個(gè)編碼的頭內(nèi)容,所以把編碼留給解讀HTTP請求的Read去做。對于默認(rèn)的請求編碼,引擎通常創(chuàng)建一個(gè)reader用“ISO-8859-1”去解析POST的數(shù)據(jù),如果客戶端沒有指明編碼,或者客戶端發(fā)送失敗,getCharacterEncoding方法就返回null。
          如果客戶端沒有設(shè)置編碼,而請求需被另外一種編碼,可用ServletRequest接口中的setCharacterEncoding(String enc) 方法。必須在解析post數(shù)據(jù)或讀取請求流之前調(diào)用這些方法。
          4.10 Request對象的生命周期
          每個(gè)request對象僅在servlet的service方法或filter中的doFilter方法中有效,引擎重用request對象是為了降低創(chuàng)建request對象的性能消耗。
          開發(fā)者必須清楚request對象在給定的范圍外的一些不確定的行為。
          第五章
           
          response對象封裝著服務(wù)端送給客戶端的信息,從服務(wù)端傳回的信息可以包含在請求的頭和消息體重。
          5.1 緩存
              servlet引擎支持應(yīng)答緩存,典型的servlet會默認(rèn)的執(zhí)行緩存,servlet可以指定緩存參數(shù)。
              設(shè)置緩存信息的方法在ServletResponse接口中的方法有:
          getBufferSize
          setBufferSize
          isCommitted
          Reset
          resetBuffer
          flushBuffer
          這些方法只有在servlet調(diào)用ServletOutputStream 或Writer之前有效。
          getBufferSize返回緩存的大小,如果沒有緩存,該方法返回0。
          setBufferSize可以設(shè)置緩存的大小,但不是必須的。servlet會根據(jù)請求放置適當(dāng)?shù)木彺娲笮 _@方法必須在servlet調(diào)用ServletOutputStream 或Writer方法之前被調(diào)用。如果在之后調(diào)用就會拋出IllegalStateException錯(cuò)誤。
          isCommitted返回一個(gè)boolen值,標(biāo)志是否有任何一個(gè)字節(jié)的數(shù)據(jù)被返回給客戶端了。flushBuffer方法強(qiáng)制把緩存中的信息寫到客戶端。
          當(dāng)response沒有提交緩存內(nèi)容時(shí)調(diào)用reset方法就會清除緩存中的信息,包括頭信息和狀態(tài)碼。resetBuffer方法會清除緩存中的信息,但不會清除頭和狀態(tài)碼。在commit之后調(diào)用reset或resetBuffer都會拋出IllegalStateException錯(cuò)誤,緩存中的內(nèi)容不受影響。
          使用緩存時(shí),當(dāng)緩存滿時(shí)response就必須立刻刷新把緩存中的內(nèi)容發(fā)送給客戶端;只要第一個(gè)字節(jié)到了客戶端,commit的狀態(tài)就為true。
          5.2 Headers
          servlet能夠通過HttpServletResponse的一些方法設(shè)置HTTP響應(yīng)的頭信息,這些方法有:
          setHeader
          addHeader
          setHeader方法會把給定的一個(gè)name-values放到頭信息中,頭信息中只能有一個(gè)name-values,后面setHeader會覆蓋前面setHeader方法中的內(nèi)容,一個(gè)name可以有多個(gè)value。
          addHeader方法可以增加一個(gè)value到已有的name上,如果name不同就會新建一個(gè)name-values
          頭可以包含一些信息,如日期或數(shù)字對象。
          以下的一些方法用適當(dāng)?shù)臄?shù)據(jù)類型設(shè)置頭信息:
          setIntHeader
          setDateHeader
          addIntHeader
          addDateHeader
          在響應(yīng)被發(fā)送到客戶端之前,頭信息是必須被設(shè)置的,如果沒有設(shè)置頭信息,servlet引擎將不會發(fā)送該請求到客戶端。HTTP1.1規(guī)范沒有規(guī)定必須設(shè)置響應(yīng)的頭信息。當(dāng)程序員沒有設(shè)置響應(yīng)體的Content-Type時(shí),servlet引擎也不需要設(shè)置一個(gè)默認(rèn)的類型。
          5.3 其他一些方法
          HttpServletResonse接口中還有其他的一些方法:
          sendRedirect
          sendError
          sendRedirect方法將設(shè)置合適的頭和體信息,用于重定向客戶端到另一個(gè)URL。如果sendRedirect參數(shù)是個(gè)相對路徑,則在底層servlet引擎中會把這相對路徑轉(zhuǎn)換成絕對路徑返回給客戶端的。
          如果相對路徑不能被引擎轉(zhuǎn)換成絕對路徑就會拋出IllegalArgumentException錯(cuò)誤。
          sendError方法會把一條錯(cuò)誤信息作為頭和體信息發(fā)送給客戶端。
          如果在調(diào)用sendRedirect或sendError之前設(shè)置了頭和體信息,再調(diào)用sendRedirect或sendError時(shí),之前的頭和體中的數(shù)據(jù)信息都將沒用,不會被發(fā)送到客戶端。如果使用了緩存,在調(diào)用sendRedirect或sendError時(shí),之前的信息都將被清除。如果在commit之后調(diào)用sendRedirect或sendError就會拋出IllegalStateException錯(cuò)誤。
          5.4 國際化
          當(dāng)客戶端用一特殊的語言(或客戶端設(shè)置了語言)發(fā)出請求時(shí),servlet會設(shè)置相應(yīng)的響應(yīng)語言信息,ServletResponse接口中設(shè)置響應(yīng)語言的方法是setLocale。這個(gè)方法會設(shè)置一個(gè)合適的Content-Language到頭信息中。最好是開發(fā)者在調(diào)用getWriter方法之前調(diào)用setLocale方法,確保返回的PrintWriter已經(jīng)被設(shè)置好了語言信息。如果在調(diào)用setLocale之后又調(diào)用了setContentType,setLocale中的內(nèi)容將被setContentType中的字符集覆蓋。
          response默認(rèn)的編碼方式是“ISO-8859-1”。
          5.5 response對象的關(guān)閉
          當(dāng)response被關(guān)閉時(shí),引擎必須刷新該response緩存中的所有內(nèi)容到客戶端。關(guān)閉的順序是:
           1)關(guān)閉servlet的service方法
           2)response 中setContentLength方法設(shè)置的指定數(shù)量的信息被寫入response
           3)調(diào)用sendError方法
           4)調(diào)用sendRedirect方法
          5.6 response對象的生命周期
          每個(gè)response對象僅在servlet的serrvice方法或filter的doFilter的方法中有效。引擎重復(fù)使用reponse對象,是為了降低創(chuàng)建response對象的開銷。開發(fā)者必須注意response對象在指定范圍外可能出現(xiàn)的一些意外的行為。
          6 Filtering
          Fileter是servlet2.3新增的部分。這一章介紹Filter類和方法,以及在web工程中的配置。
          6.1什么是Fileter
          Filter是重復(fù)使用的,用于變換HTTP請求和響應(yīng)以及頭信息中的內(nèi)容。Filter不能像servlet那樣創(chuàng)建response響應(yīng),但可以修改請求和響應(yīng)的內(nèi)容。
          6.1.1例舉一些Filter
          驗(yàn)證Filter
          登陸,審核Filter
          圖像處理Filter
          數(shù)據(jù)壓縮Filter
          加密Filter
          XSL/T Filter
          MIME Filter
          6.2 主要觀念
          開發(fā)者通過創(chuàng)建實(shí)現(xiàn)javax.servlet.Filter接口的類,并提供一個(gè)沒有參數(shù)的構(gòu)造函數(shù)來創(chuàng)建一個(gè)Filter。
          在描述文件中Fileter用filter表示,調(diào)用方法用filter-mapping進(jìn)行配置。
          6.3 Filter生命周期
          在web工程發(fā)布后,在請求使引擎訪問一個(gè)web資源之前,引擎必須定位Filter列表;引擎必須確保為列表中的每一個(gè)Filter建立了一個(gè)實(shí)例,并調(diào)用了他們的init(FilterConfig config)方法。在這過程中可以拋出異常。
          部署描述文件中定義的所有filter,僅會在引擎中產(chǎn)生一個(gè)實(shí)例。
          引擎為filter提供了一個(gè)FilterConfig類,該類附有ServletContext和一個(gè)帶有初始化參數(shù)的set。
          當(dāng)引擎接受一個(gè)請求時(shí),引擎就會調(diào)用filter列表中第一個(gè)filter的doFilter方法,把ServletRequest,ServletResponse和FilterChain作為參數(shù)傳給它。
          filter中doFilter方法典型的處理步驟是:
          1)檢查請求頭信息
          2)開發(fā)者創(chuàng)建一個(gè)實(shí)現(xiàn)了ServletRequest或HttpServletRequest的類,去包裝request對象,以便修改請求的頭信息或體數(shù)據(jù)。
          3)開發(fā)者創(chuàng)建一個(gè)實(shí)現(xiàn)了ServletReqponse或HttpServletResponse的類,去包裝response對象,以便修改請求的頭信息或體數(shù)據(jù)。
          4)filter可以調(diào)用鏈中的下一個(gè)實(shí)體,下一個(gè)實(shí)體是另一個(gè)filter,如果該filter是列表中最后的一個(gè),則它的下一個(gè)實(shí)體就是一個(gè)目標(biāo)web資源。如果要調(diào)用下一個(gè)filter的doFilter方法,把request,和response對象傳給FilterChain對象的doFilter方法中就可以了。
          Filter chain 的doFilter方法是由引擎提供的,引擎在該方法中會定位filter列表中的下一個(gè)filter,調(diào)用它的doFilter方法,把傳來的request和response對象傳給它。
          5)在調(diào)用chain.doFilter之后,filter可以檢測響應(yīng)的頭信息
          6)在這些過程中,filter可以拋出異常。當(dāng)在調(diào)用doFilter過程中拋出UnavailableException異常時(shí),引擎重復(fù)嘗試處理下面的filter chain的方法,如過時(shí)后還沒請求到filter chain 就會關(guān)閉對filter chain的請求。
          當(dāng)filter是列表中最后一個(gè)filter時(shí),它的下一個(gè)實(shí)體是描述配置文件中filter后面的servlet或其它資源。
          在引擎刪除一個(gè)Filter之前,引擎必須調(diào)用Filter的destroy方法,來釋放資源。
          6.3.1 包裝Requests 和Responsees
          過濾的中心觀念是對request或response的包裝,在這種模式下,開發(fā)者不僅可以改寫存在的方法,還可以創(chuàng)建自己的新方法,用于特殊的過濾任務(wù),例如:開發(fā)者希望擴(kuò)展response對象,希望有個(gè)更高層次的輸出流對象(writer)。
          為了支持包裝模式,引擎不許保證在整個(gè)過濾鏈中,傳遞的request和response對象都是同一個(gè)對象。
          6.3.2 Filter的環(huán)境
          Filter的初始參數(shù)可以在描述配置文件中用init-params元素來配置,在運(yùn)行時(shí)中,用FilterConfig的getInitParameter和getInitParamesterNames方法得到配置參數(shù)。
          6.3.3 Filter在web工程中的配置
          在部署描述文件中:
          filter-name:filter名稱
          filter-class:filter類路徑
          init-params:用于初始化參數(shù)
          如果開發(fā)者在部署描述中為一個(gè)filter類描述了兩個(gè)定義,則引擎會創(chuàng)建這個(gè)filter類的兩個(gè)實(shí)例。
          下面是個(gè)配置的例子:
          <filter>
          <filter-name>Image Filter</filter-name>
          <filter-class>com.acme.ImageServlet</fiflter-class>
          </filter>
          一旦filter在部署描述中定義,filter-mapping就可以被定義了,filter-mapping在web應(yīng)用中是定義關(guān)聯(lián)filter的servlet和靜態(tài)資源的。
          如:
          <filter-mapping>
          <filter-name>Image Filter</filter-name>
          <servlet-name>ImageServlet</servlet-name>
          </filter-mapping>
          Image Filter 的 Filter就和ImageServlet 的Servlet建立了關(guān)聯(lián)。
          Filter 可以和一群servlet和靜態(tài)資源關(guān)聯(lián),用url-pattern。如:
          <filter-mapping>
          <filter-name>Loging Filter</filter-name>
          <url-pattern>/*</url-pattern>
          <filter-mapping>
          引擎建立特殊請求URI的Filter鏈的順序是:
          1)url-pattern映射fiter-mapping的順序和描述文件中定義的順序是一樣的。
          2)servlet-name映射filter-mapping的順序和描述文件中定義的順序是一樣的。
          這種需求要求引擎在接受請求時(shí):
          .識別符合SRV.11.2規(guī)則的web資源。
          .如果一些filter是servlet和有servlet-name的web資源匹配的,引擎就會創(chuàng)建一個(gè)和描述文件中映射servlet-name的順序一樣的filter鏈。
          .如果一些filter是rul-pattern關(guān)聯(lián)的,引擎就會創(chuàng)建一個(gè)和描述文件中映射url-pattern的順序一樣的efilter鏈。
          一個(gè)高性能的web容器將會緩存filter鏈。
          第七章 Sessions
          超文本傳輸協(xié)議(HTTP)是無狀態(tài)的協(xié)議。要建立一個(gè)有效的web應(yīng)用,客戶端之間的通信是需要的。有很多會話跟蹤的策略,
          但是直接使用這些技術(shù)都很難使用。servlet規(guī)范中提供了一個(gè)簡單的HttpSession接口,不需要開發(fā)者關(guān)心會話跟蹤的具體細(xì)節(jié)。
          7.1 會話跟蹤機(jī)制
          下面描述了幾種會話的跟蹤機(jī)制
          7.1.1 Cookies
          HTTP cookies是最常用的會話跟蹤機(jī)制,所有的servlet引擎都應(yīng)該支持這種方法。
          引擎發(fā)送一個(gè)cookie到客戶端,客戶端就會在以后的請求中把這個(gè)cookie返回給服務(wù)器。用戶會話跟蹤的cookie的名字必須是JSESSIONID
          7.1.2 SSL Sessions
          在安全套接字層,加密技術(shù)用在了HTTPS協(xié)議,從一個(gè)客戶端來的多個(gè)請求允許用一個(gè)含糊的標(biāo)識,servlet引擎就用這個(gè)數(shù)據(jù)定義一個(gè)Session。
          7.1.3 URL重寫
          URL重寫是最低性能的通用會話跟蹤方法。當(dāng)一個(gè)客戶端不能接受cookie時(shí),URL重寫就會作為基本的會話跟蹤方法;URL重寫包括一個(gè)附加的數(shù)據(jù),一個(gè)session id,這樣的URL會被引擎解析和一個(gè)session相關(guān)聯(lián)。一個(gè)session id是作為URL的一個(gè)被編碼的參數(shù)傳輸?shù)模@個(gè)參數(shù)名字必須是jsessionid.如下面的例子:
          http://www.myserver.com/catalog/index.html;jsessionid=1234
          7.1.4 會話的完整性
          一個(gè)web容器必須支持HTTP 會話。而當(dāng)cookies方法不被支持時(shí),通常使用URL重寫方法。
          7.2 創(chuàng)建一個(gè)會話
          servlet設(shè)計(jì)者必須考慮到一個(gè)客戶端不能加入session的情況。
          7.3 會話范圍
          HttpSession對象只在應(yīng)用程序級有效,通常用于session的cookie可以服務(wù)于不同的上下文,但一個(gè)HttpSession實(shí)例只服務(wù)于一個(gè)會話。舉個(gè)例子:如一個(gè)servlet A用RequestDispatcher去調(diào)用另一個(gè)web應(yīng)用中的另一個(gè)servlet B,用于A和B的會話一定是兩個(gè)不同的會話。
          7.4 Session屬性的邦定
          一個(gè)servlet可以通過一個(gè)name邦定一個(gè)對象到HttpSession實(shí)例中;只要獲得包含同一個(gè)會話的請求對象,任何邦定到會話中的對象在同一個(gè)ServletContext中對于其它的servlet都是可用的。
          當(dāng)把一個(gè)對象放入session或從session刪除時(shí)可能要通知其它對象,這些信息能夠被實(shí)現(xiàn)了HttpSessionBindingListener接口的對象獲得,這個(gè)接口定義了一下的一些方法。
          valueBound
          valueUnbound
          valueBound方法在HttpSession接口調(diào)用getAttribute方法獲得一個(gè)有效的對象之前調(diào)用。valueUnbound方法在HttpSession接口調(diào)用getAttribute方法獲得一個(gè)不再有效的對象后調(diào)用。
          7.5 會話超時(shí)
          在HTTP協(xié)議中,當(dāng)客戶端不再有效時(shí),沒有清楚的定義終止信號。這就意味著通常只能采用時(shí)間超時(shí)來表明客戶端不再有效。
          默認(rèn)的超時(shí)時(shí)間是servlet引擎定義的,通過HttpSession的getMaxInactiveInterval方法可以得到超時(shí)的時(shí)間;開發(fā)者可用用setMaxInactiveInterval方法來設(shè)置超時(shí)的時(shí)間,以秒定義的。如果一個(gè)session的超時(shí)時(shí)間被設(shè)置為-1,則這個(gè)session將永遠(yuǎn)有效。
          7.6 最后訪問時(shí)間
          在當(dāng)前的請求中用HttpSession接口的getLastAccessedTime可以獲得最后一次訪問session的時(shí)間。
          7.7 重要session
          7.7.1 線程問題
          在一個(gè)可以配置的應(yīng)用中,所有的請求都是一個(gè)會話的一部分,引擎一定能夠取出通過setAttribute或putValue放入HttpSession對象中的對象。注意以下的情況:
          .引擎一定能夠訪問實(shí)現(xiàn)了Serializable接口的對象。
          .引擎可以選擇存儲HttpSession對象中指定的對象,如EJB組件和事務(wù)。
          .引擎能夠監(jiān)聽到會話的變動(dòng)。
          如果放入session中的對象沒有被Seializable或沒有效,servlet可以拋出IllegalArgumentException;如果引擎不支持Session存儲對象的機(jī)制,引擎一定會拋出IllegalArgumentException。
          這些限制意味著,在一個(gè)分布式引擎中,不會有額外的并發(fā)問題。
          如果引擎為了service的品質(zhì)持續(xù)化或遷移session,使用本地持續(xù)化的HttpSession或它的屬性是不受限制的,開發(fā)者要想確保放入session中的屬性對象能夠可用,最好對象實(shí)現(xiàn)Serializable接口。
          在遷移一個(gè)session時(shí)引擎必須通知session中實(shí)現(xiàn)了HttpSessinActivationListener的屬性對象,必須通知在序列化前鈍化的或序列化后激活的session的監(jiān)聽器。
          開發(fā)分布式的開發(fā)者應(yīng)該清楚的是,一旦引擎運(yùn)行在超過一個(gè)JVM的時(shí)候,就不能用static 表明變量來存儲應(yīng)用狀態(tài),應(yīng)該用EJB或數(shù)據(jù)庫賴存儲。
          7.7.3客戶端
          因?yàn)閏ookies或SSL證書都是被web瀏覽器訪問過程控制的,與任何特殊的window瀏覽器是沒有關(guān)系的。所以從所有window客戶端到一個(gè)servlet引擎的請求是同一個(gè)會話的一部分。最好是開發(fā)者總是設(shè)想所有的window客戶端是一起參與同一個(gè)會話的。
           
          第八章 Dispatching Requests
          當(dāng)建立一個(gè)web應(yīng)用時(shí),把一個(gè)請求傳給另一個(gè)servlet或在response中包含另一個(gè)servlet的輸出是經(jīng)常使用的。RequestDispatcher接口就提供了一些方法。
          8.1 獲得RequestDispatcher
          實(shí)現(xiàn)了接口RequesetDispatcher接口的對象可以在ServletContext的getRequestDispatcher或getNamedDispatchcer方法得到。
          getRequestDispatcher的參數(shù)是一個(gè)以根目錄‘/’開始的一個(gè)路徑,該方法會查找路徑下的servlet,并把它封裝成RequestDispatchcer對象返回。
          getNamedDispatcher方法把一個(gè)ServletContext知道的servlet名字作為參數(shù),如果找到servlet,該servlet就被封裝成RequestDispatcher對象返回,如果沒有找到則返回null。
          RequestDispatcher對象中使用相對路徑也是可以的。在ServletRequest中提供了getRequestDispatcher方法;這個(gè)方法和ServletContext中同名的方法功能類似。servlet引擎會用request的信息把相對路徑轉(zhuǎn)化成完整路徑的。如ServleltRequest.getRequestDispatcher("header.html")和ServletConext.getRequestDispatcher("/garden/headere.html")是等效的。
          8.1.1 在Request Dispatcher 路徑中附加字符串
          在ServletContext和ServletRequest創(chuàng)建RequestDispatcher方法中參數(shù)都可以帶字符串如:
          Context.getRequestDispatcher("/raisons.jsp?orderno=5");
          8.2 Request Dispatcher的使用
          對于使用Request Dispatcher 而言就是一個(gè)servlet調(diào)用include或forward方法,這些方法的參數(shù)是Servlet接口傳來的request和response對象實(shí)例。引擎必須確保調(diào)用Request Dispatcher的處理過程是在同一個(gè)JVM的同一個(gè)線程中。
          8.3 include 方法
          RequestDispatcher接口的include方法可以在任何時(shí)候被調(diào)用;目標(biāo)servlet可以包含所有外的request對象,不過response對象的使用是有限制的:
          response只能寫信息到ServletOutputStream 或者Writer中,調(diào)用response對象的flushBuffer方法進(jìn)行提交。不能夠設(shè)置頭信息,任何方法都不會影響到response的頭信息。
          8.3.1 被包含的request參數(shù)
          除了可以用getNamedDispatcher方法包含一個(gè)servlet外,以下的屬性可以被設(shè)置:
          Java.servlet.include.request_uri
          Java.servlet.include.context_path
          Java.servlet.include.servlet_path
          Java.servlet.include.path_info
          Java.servlet.include.query_string
          用request對象的getAttribute方法可以獲取被包含servlet的以上屬性。
          如果被包含的servlet能后通過getNamedDispatcher方法找到就不必設(shè)置以上屬性了。
          8.4 Forward 方法
          RequestDispatcher接口中的forward方法,只有servlet沒有提交響應(yīng)到客戶端時(shí)才可用;如果響應(yīng)buffer中有數(shù)據(jù)還沒有提交,當(dāng)調(diào)用forward方法中目標(biāo)servlet的service方法前,buffer中的內(nèi)容會被清空;如果buffer中的數(shù)據(jù)提交了,則發(fā)生IllegalStateException錯(cuò)誤。
          request對象的路徑必須放映獲取RequestDispatcher對象的路徑。
          有個(gè)例外,如果RequestDispatcher是通過getNamedDispatcher方法得到的,request對象必須反映原始request的路徑。
          在RequestDispatcher接口方法forward返回前,response的內(nèi)容必須被提交,并由引擎關(guān)閉該servlet。
          8.4.1 query String
          在Request Dispatcher中創(chuàng)建的路徑是可以帶參數(shù)的。
          8.5 錯(cuò)誤
          如果request Dispatcher的目標(biāo)servlet拋出運(yùn)行時(shí)錯(cuò)誤或ServletException 或IOException,錯(cuò)誤就會被傳給調(diào)用的servlet;在上傳之到調(diào)用的servlet之前,所有其他的exception都應(yīng)該包裝成ServletExceptions。
           
          第九章 web 應(yīng)用
          一個(gè)web應(yīng)用是一堆servlet,html頁面,類和其他資源的集合。web應(yīng)用可以被發(fā)布運(yùn)行在很多服務(wù)提供商的多種引擎下。
          9.1 web服務(wù)器
          在web服務(wù)中一個(gè)web應(yīng)用的根目錄是一個(gè)特殊的路徑,例如:一個(gè)網(wǎng)站目錄可以以http://www.mycorp.com/登錄,所有的請求都將以這個(gè)作為前綴發(fā)送到以這個(gè)前綴描述的servletContext環(huán)境中。
          在任何時(shí)候一個(gè)web應(yīng)用的實(shí)例只能運(yùn)行在一個(gè)JVM中。
          9.2 和servletContext的關(guān)系
          servlet引擎會強(qiáng)迫web應(yīng)用和ServletContext的通信,一個(gè)ServletContext對象提供了一個(gè)servlet使得該應(yīng)用可見。
          9.3 web應(yīng)用中的元素
          一個(gè)web應(yīng)用包含以下的元素:
          .Servlets
          .JSP
          .Utility Classes
          .Static documents(html,images,sounds,etc)
          .Client side Java applets,beans,and classes
          .Descriptive meta informateion
          9.4 部署層次
          這個(gè)協(xié)議定義了一個(gè)層次結(jié)構(gòu),用于部署和打包,這個(gè)結(jié)構(gòu)存在于一個(gè)文件中。
          9.5 目錄結(jié)構(gòu)
          一個(gè)web應(yīng)用存在一個(gè)目錄層次結(jié)構(gòu)。文件根目錄是應(yīng)用的一部分。例如:一個(gè)web應(yīng)用的上下文路徑是/catalog,web應(yīng)用的index.html文件就能被/catalog/index.html請求訪問。URL和上下文路徑的匹配規(guī)則將在11章討論。servlet引擎必須拒絕一個(gè)具有現(xiàn)在沖突的上下文路徑的web應(yīng)用,這種情況是有的,如:兩個(gè)web應(yīng)用發(fā)布在同一個(gè)上下文路徑中,或一個(gè)web應(yīng)用的上下文路徑是另一個(gè)web應(yīng)用上下文路徑的子路徑。
          有一個(gè)特殊的目錄(“WEB-INF”)在應(yīng)用中存在,這個(gè)目錄包含所有與應(yīng)用相關(guān),又不在根目錄中的事物。可以直接被引擎提供給客戶端的文件不放在WEB-INF中,但WEB-INF目錄對于調(diào)用ServletContext的getResource和getResourceAsStream方法的servlet 代碼是有效的。如果開發(fā)者想用servlet代碼調(diào)用一個(gè)不希望暴露給客戶端的一個(gè)配置信息,就可以把這個(gè)配置信息放在WEB-INF目錄下。請求都是和資源相匹配的;敏感的匹配如客戶端的請求是“/WEB-INF/foo”和“/Web-iNf/foo”,但不應(yīng)該把定位于/WEB-INF下的內(nèi)容作為結(jié)果返回。
          WEB-INF目錄下的內(nèi)容有:
          ./WEB-INF/web.xml 部署描述文件
          ./WEB-INF/classes/ 存放servlet class
          ./WEB-INF/lib/*.jar 是jar包的目錄
          應(yīng)用的classloader先load WEB-INF/classes目錄下的class后load WEB-INF/lib目錄下的jar包
          9.5.1 目錄結(jié)構(gòu)的一個(gè)例子
          一個(gè)簡單web應(yīng)用的目錄結(jié)構(gòu):
          /index.html
          /howto.jsp
          /images/banner.gif
          /images/jumping.gif
          /WEB-INF/web.xml
          /WEB-INF/lib/jspbean.jar
          /WEB-INF/classes/com/mycorp/servlets/MyServlet.class
          /WEB-INF/classes/com/util/MyUtils.class
           
          9.6 web應(yīng)用的存檔文件
          一個(gè)web應(yīng)用可以被java打包工具打包成war文件,當(dāng)被打包后包中就會有一個(gè)額外META-INF目錄,該目錄下存放了打包工具的一些信息。
          9.7 web應(yīng)用部署描述
          下面是web應(yīng)用部署描述中的配置類型:
          .ServletContext Init Parameters
          .Session Configuration
          .Servlet / JSP Definitions
          .Servlet / JSP Mappings
          .MIME Type Mappings
          .Welcome File list
          .Error Pages
          .Security
           
          9.7.1 可靠的擴(kuò)展
          web容器須提供一種機(jī)制使得web應(yīng)用知道jar文件中包含的有用資源或代碼。
          引擎因該提供編輯、配置庫文件的程序。
          在WAR中提供一個(gè)MANIFEST.MF文件,描述擴(kuò)展名列表是比較好的。標(biāo)準(zhǔn)的JAR是應(yīng)該有的,這個(gè)文件描述的擴(kuò)展名應(yīng)該遵循Http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html中的規(guī)定。web容器應(yīng)該能夠識別WEB-INF/lib文件夾中的任何文件的擴(kuò)展名,如果不能夠識別就應(yīng)該拒絕該應(yīng)用程序,并報(bào)出錯(cuò)誤。
          9.7.2 web應(yīng)用的classloader
          引擎用于裝載war中的servlet的裝載器必須能夠讓開發(fā)者裝載jar庫中的任何資源。但裝載的資源禁止覆蓋j2se或servlet API中的類;通常建議的做法是裝載器不允許war中的servlet去訪問web引擎中的類。
          還有一個(gè)被推薦的做法是實(shí)現(xiàn)應(yīng)用類裝載器,war中被裝載的類或資源就會被放到container-wide JAR庫的特定類或資源中。
          9.8 替換web應(yīng)用
          一個(gè)服務(wù)器可能會在不重新啟動(dòng)引擎的情況下用一個(gè)新版本的應(yīng)用替換原有的應(yīng)用。當(dāng)一個(gè)應(yīng)用被替換時(shí),引擎應(yīng)提供一個(gè)robust方法去保存該應(yīng)用中的session
          9.9 錯(cuò)誤句柄
          9.9.1 request Attributes
          web應(yīng)用必須列出在使用中資源發(fā)生的錯(cuò)誤,這些資源在部署描述中都有定義。
          如果錯(cuò)誤在一個(gè)servlet或一個(gè)jsp頁面中發(fā)生,則在第9.1章中的如下的請求屬性就會被設(shè)置:
          Request Attributes                               Type
          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
          這些屬性允許這個(gè)servlet根據(jù)這些狀態(tài)碼、錯(cuò)誤類型、錯(cuò)誤信息、被拋出的錯(cuò)誤對象、錯(cuò)誤產(chǎn)生的servlet被訪問的URI(可以用getRequestURI得到)、或錯(cuò)誤產(chǎn)生的servlet的邏輯名稱產(chǎn)生特殊的內(nèi)容。
          在2.3版本中錯(cuò)誤類型和錯(cuò)誤信息屬性是多余的,他們被保留只是為了向下兼容以前的版本。
          9.9.2 錯(cuò)誤頁面
          當(dāng)一個(gè)servlet產(chǎn)生錯(cuò)誤時(shí),開發(fā)者可以訂制錯(cuò)誤內(nèi)容返回給客戶端。部署描述文件定義了一個(gè)錯(cuò)誤頁面列表。servlet在response中設(shè)置錯(cuò)誤狀態(tài)碼或產(chǎn)生的異?;蝈e(cuò)誤被引擎支持時(shí),引擎就會從部署描述文件中調(diào)用相應(yīng)的配置的錯(cuò)誤資源。
          如果一個(gè)錯(cuò)誤碼被設(shè)置在了response中,引擎在部署描述文件的錯(cuò)誤頁面列表中用status-code方式匹配對應(yīng)的資源,如果找到就調(diào)用本地的資源。
          在一個(gè)請求被處理的過程中servlet可以拋出以下的異常:
          .runtime exceptions or errors
          .ServletExceptions or subclasses thereof
          .IOException or subclasses thereof
          web應(yīng)用可以用exception-type元素來描述錯(cuò)誤頁面,在這種情況下引擎會通過比較用exception-type元素定義的error-page列表中的異常來匹配產(chǎn)生的異常。匹配的結(jié)果是返回定義的與錯(cuò)誤匹配的本地資源。在繼承類中,最近的類將被調(diào)用。
          如果沒有一個(gè)error-page包含的exception-type與class-heirarchy相匹配。拋出的ServletException或其子類異常,被引擎通過ServletException.getRootCause方法獲得,獲得后用這個(gè)異常再去配置的error page列表中去匹配。
          在部署描述文件中用exception-type元素定義的Error-page中exception-type的類名必須是唯一的。
          當(dāng)錯(cuò)誤發(fā)生在servlet調(diào)用的RequestDispatcher中時(shí)error page機(jī)制是不能夠干預(yù)到的;這樣的情況如:一個(gè)servlet用RequestDispatcher去調(diào)用另一個(gè)有錯(cuò)誤的servlet。
          如果一個(gè)servlet產(chǎn)生的錯(cuò)誤沒有被描述的錯(cuò)誤頁面機(jī)制所抓到,引擎必須設(shè)置response的狀態(tài)碼為500
          9.10 Welcome Files
          web應(yīng)用可以在部署描述文件中定義一個(gè)welcome files調(diào)用的URI列表,這個(gè)機(jī)制的目的是允許開發(fā)者定義自己的訪問首頁。
          如果沒有在部署描述中配置welcome 文件,引擎將把局部請求(沒有指明具體訪問資源,如www.cacolg.com/index.html,請求訪問時(shí)用www.cacolg.com/訪問的)發(fā)送到適當(dāng)?shù)馁Y源中,如:一個(gè)可能默認(rèn)的servlet,或列出該目錄下的文件列表,或返回404響應(yīng)錯(cuò)誤。
          一個(gè)例子:
          1)在部署描述中定義index.html和default.jsp為welcome files
          2)定義一個(gè)servlet的mapping路徑為/foo/
             WAR中有的文件如下:
             /foo/index.html
             /foo/default.html
             /foo/orderform.html
             /foo/home.gif
             /catalog/default.jsp
             /catalog/products/shop.jsp
             /catalog/products/register.jsp
          3)請求的URI為                    處理后的URI
           /foo 或 /foo/                    /foo/index.html
           /catalog/                        /catalog/default.jsp
           /catalog/index.html           404 not found
           /catalog/products/            404 not found 也可能返回shop.jsp and /or register.jsp 列表。
          9.11 web應(yīng)用環(huán)境
           
          j2EE定義的命名環(huán)境能夠使得應(yīng)用在不需要知道外部信息怎么命名的情況下比較方便的訪問資源或外部信息。
          servlet作為j2EE完整的一部分,使web應(yīng)用部署描述文件提供了一個(gè)servlet可以訪問資源和EJB,這些部署描述元素有:
          .env-entry
          .ejb-ref
          .ejb-local-ref
          .resource-ref
          .resource-env-ref
          開發(fā)者使用這些元素描述web應(yīng)用中需要用到的對象,這些對象都要在web容器運(yùn)行時(shí)注冊到JNDI命名空間。
          在J2EE1.3版本j2EE的環(huán)境需求中,servlet引擎不是J2EE技術(shù)的一部分,web環(huán)境要提供的功能在J2EE規(guī)范中有描述。如果沒有實(shí)現(xiàn)支持環(huán)境所要提供的功能,在發(fā)布應(yīng)用時(shí),web容器就會拋出警告。
          實(shí)現(xiàn)servlet引擎在J2EE中是需要的,應(yīng)該被納入J2EE1.3中。J2EE1.3應(yīng)該提供更多的內(nèi)容。
          servlet引擎必須支持對象的lookup方法,查找對象并在引擎控制的線程中實(shí)例化。
          servlet引擎應(yīng)該支持開發(fā)者創(chuàng)建的線程,因?yàn)閼?yīng)用創(chuàng)建的線程不是很輕便,開開發(fā)者不得不依賴于這些功能有限的線程。這些需求將被加入到下一個(gè)版本的servlet規(guī)范中。
           
          第十章 應(yīng)用周期事件
          10.1 介紹
          事件是servlet2.3種新添的內(nèi)容。應(yīng)用事件使得web開發(fā)者能夠控制ServletContext和HttpSession對象的信息交互,使得管理web使用的資源更有效,方便。
          10.2 事件監(jiān)聽器
          事件監(jiān)聽器是實(shí)現(xiàn)了servlet事件監(jiān)聽接口的類。在web發(fā)布是這些監(jiān)聽類就被實(shí)例化和注冊在web容器中。
          servlet事件監(jiān)聽器提供了在ServletContext和HttpSerssion對象狀態(tài)發(fā)生改變時(shí)觸發(fā)的事件。Servlet cotext監(jiān)聽器用于管理應(yīng)用的資源或虛擬機(jī)的狀態(tài)。HTTP session監(jiān)聽器管理與會話關(guān)聯(lián)的資源。
          可以有多個(gè)監(jiān)聽器監(jiān)聽每一個(gè)事件類型。開發(fā)者可以指定引擎調(diào)用監(jiān)聽類的順序。
          10.2.1 事件類型和監(jiān)聽接口
          Event Type                                 ListenerInterface                                 說明
          Lifecycle                      javax.servlet.ServletContextListener              當(dāng)servlet context被創(chuàng)建并有效的接受第一個(gè)請求
                                                                                                 或servlet context銷毀前
          Changes to attributees   javax.servlet.ServletContextAttributesListener 當(dāng)servlet context中的屬性發(fā)生added,removed,replaced
           
          Lifecycle                      javax.servlet.http.HttpSessionListener            當(dāng)HttpSession被創(chuàng)建,無效或超時(shí)
          Changes to attributes     javax.servlet.HttpSessionAttributesListener     當(dāng)屬性added,removed或replaced時(shí)
          10.2.2 一個(gè)使用監(jiān)聽的例子
          一個(gè)簡單的web應(yīng)用中有servlet要訪問數(shù)據(jù)庫,開發(fā)者提供一個(gè)context 監(jiān)聽類管理數(shù)據(jù)庫連接。
          1)web應(yīng)用啟動(dòng)時(shí),監(jiān)聽類被裝載,登陸數(shù)據(jù)庫,在servlet context中保存數(shù)據(jù)庫連接。
          2)servlet訪問數(shù)據(jù)庫連接
          3)當(dāng)web服務(wù)銷毀時(shí),或應(yīng)用從web服務(wù)中刪除時(shí),關(guān)閉數(shù)據(jù)庫連接。
          10.3 監(jiān)聽類的配置
          10.3.1 對監(jiān)聽類的規(guī)定
          web開發(fā)者提供實(shí)現(xiàn)了以上監(jiān)聽接口的類,每個(gè)類應(yīng)該有一個(gè)沒有參數(shù)的構(gòu)造器函數(shù)。監(jiān)聽類放在WEB-INF/classes下或以一個(gè)jar文件放在WEB-INF/lib下都可以。
          10.3.2 部署描述
          web容器對每個(gè)監(jiān)聽類只會創(chuàng)建一個(gè)實(shí)例,在第一個(gè)請求到來之前實(shí)例化并注冊。web容器注冊監(jiān)聽類的順序根據(jù)他們實(shí)現(xiàn)的接口和在部署描述文件中定義的順序。web應(yīng)用調(diào)用監(jiān)聽實(shí)例的順序按照他們注冊的順序。
          10.3.4 在銷毀時(shí)的事件
          當(dāng)應(yīng)用銷毀時(shí)監(jiān)聽事件的執(zhí)行順序按部署描述中的順序,先執(zhí)行session中的監(jiān)聽事件再執(zhí)行context中的監(jiān)聽事件。session的無效事件必須在context的銷毀事件之前被調(diào)用。
          10.4 部署描述的例子
          下面給出注冊兩個(gè)servlet cocntext lifecycle監(jiān)聽器和一個(gè)HttpSession監(jiān)聽器的例子。
          Com.acme.MyconnectionManager和com.acme.MyLoggingMoudule都實(shí)現(xiàn)了javax.servletServletContextListener接口,com.acme.MyloggingModule另外還實(shí)現(xiàn)了javax.servlet.HttpSessionListener接口。開發(fā)者希望com.acme.MyConnectionManager在com.acme.MyLoggingModule之前管理者servlet context 的生命周期事件。部署描述文件如下:
          <web-app>
           <display-name>MyListeningApplication</display-name>
           <listener>
              <listener-class>com.acme.MyConnectionManager</listener-class>
           </listenrer>
           <listenrer>
              <listenrer-class>com.acme.MyLoggingModele</listener-class>
           </listener>
           <sevlet>
              <display-name>RegistrationServlet</display-name>
              ..etc
           </servlet>
          </web-app>
          10.5 監(jiān)聽器的實(shí)例和線程
          在第一個(gè)請求被web容器接受之前實(shí)例化并注冊好監(jiān)聽器類是必須的。監(jiān)聽器在整個(gè)web應(yīng)用生命周期中都要使用。
          ServletContext和HttpSession對象屬性的改變可能會同時(shí)產(chǎn)生,引擎不需要同步這些屬性類的事件。
          10.6 分布式容器組
          在分布式web容器組中,HttpSession和ServletContext實(shí)例只活動(dòng)與它們本地的JVM中。在分布式web容器中,監(jiān)聽實(shí)例會在每一個(gè)web容器中創(chuàng)建實(shí)例。
          10.7 session事件
           監(jiān)聽器使得開發(fā)者可以跟蹤web應(yīng)用中的session。知道session是否變得無效是經(jīng)常被用到的,因?yàn)閟ession超時(shí)時(shí)引擎會使session變得無效,或應(yīng)用會調(diào)用invalidate方法。
           
          第十一章 請求到servlet的映射
          11.1 URI的使用
          web容器根據(jù)客戶端的請求決定要調(diào)用的資源。
          URL路徑映射規(guī)則是第一個(gè)匹配成功就不再匹配了。
          1)引擎將盡力為每一個(gè)請求一個(gè)servlet的路徑匹配一個(gè)servlet
          2)引擎將遞歸的匹配最長的路徑前綴(在一個(gè)目錄樹中)
          3)如果在URL路徑中的最后一節(jié)有擴(kuò)展名(例如:.jsp),則servlet引擎將會匹配一個(gè)適當(dāng)?shù)膕ervlet獲取請求對象
          4)如果沒有一個(gè)servlet能夠匹配請求,引擎將用一個(gè)適當(dāng)?shù)馁Y源來處理該請求。如:在應(yīng)用中配置了默認(rèn)的servlet,就會被用來處理匹配不到資源的請求。
          11.2 匹配規(guī)則
          在web應(yīng)用描述文件中,匹配的定義如下:
          .以'/'開始,以'/*'為結(jié)尾的字符串,用作路徑匹配
          .以'*.'開始的字符串,用作擴(kuò)展名匹配
          .包含'/'字符串,定義一個(gè)默認(rèn)的servlet。如匹配的servlet路徑是請求URI路徑的最小上下文路徑,路經(jīng)的info為空。
          .其它的字符串用作精確的匹配。
          11.2.1 絕對匹配
          servlet引擎能夠匹配任何精確的資源,如后綴為*.jsp的匹配,引擎中有JSP引擎的話,就會把所有的JSP頁面和與之對象的資源相匹配。
          11.2.2 匹配的例子:
                  path pattern                                servlet
          /foo/bar/*                                          servlet1
          /baz/*                                               servlet2
          /catalog                                             servlet3
          *.bop                                                 servlet4
           
                  incoming path                             servlet handling request
           /foo/bar/index.html                            servlet1
           /foo/bar/index.bop                             servlet1
           /baz                                                servlet2
           /baz/index.html                                  servlet2
           /catalog                                           servlet3
           /catalog/racecar.bop                          servlet4
           /index.bop                                        servlet4
           
          第十二章 安全
          12.1介紹
          web應(yīng)用的資源能夠被很多的用戶訪問,這些資源經(jīng)常沒有保護(hù)的暴露在網(wǎng)絡(luò)中,因此一個(gè)穩(wěn)定的web應(yīng)用需要一個(gè)安全的環(huán)境。
          提高安全性有以下的幾個(gè)方面:
          .認(rèn)證:訪問一個(gè)實(shí)例前需要一個(gè)特殊的ID進(jìn)行授權(quán)認(rèn)證后才能訪問該實(shí)例
          .資源的訪問控制:一些機(jī)密資源或局部資源只限制給某些用戶或程序使用。
          .數(shù)據(jù)完整性:在傳輸過程中數(shù)據(jù)不能被意外的改變。
          .機(jī)密性:確定信息只能被授權(quán)過的用戶使用。
          12.2 公共安全
          安全性聲明是指表明應(yīng)用是有安全結(jié)構(gòu)的;包括權(quán)限、訪問控制、認(rèn)證。在web應(yīng)用中部署描述是安全聲明的主要工具。
          開發(fā)者應(yīng)該為應(yīng)用運(yùn)行時(shí)配一個(gè)邏輯安全策略,在運(yùn)行時(shí)中,servlet引擎用這個(gè)安全策略去驗(yàn)證授權(quán)請求。
          安全模塊應(yīng)該適用web應(yīng)用的靜態(tài)內(nèi)容,當(dāng)servlet用RequestDispatcher調(diào)用一個(gè)靜態(tài)資源或servlet用forward或include,時(shí)安全模塊不適用。
          12.3 程序級安全
          當(dāng)應(yīng)用的安全模塊不能充分的表明安全時(shí)程序安全就可以被使用。
          程序安全有以下部分組成:
          HttpServletRequest接口:
          .getRemoteUser
          .isUserInRole
          .getUserPrincipal
          getRemoteUser方法返回客戶端用戶的名稱,用于授權(quán)。
          isUserInRole方法判斷遠(yuǎn)程用戶是否在一個(gè)安全的角色內(nèi)。
          getUserPrincipal方法返回一個(gè)java.security.Principal對象,表明當(dāng)前用戶的主要名稱。這個(gè)API允許servlet根據(jù)這個(gè)信息處理一些業(yè)務(wù)邏輯。
          如果用戶沒有授權(quán),getRemoteUser返回null,isUserInRole返回false,getUserPrincipal返回null。
          isUserInRole以一個(gè)role-name為參數(shù)。一個(gè)security-role-ref元素為在部署描述文件中定義,role-name子元素包含角色名稱。Security-role包含一個(gè)子元素role-link,role-link的value值是客戶端用戶將匹配的安全角色。當(dāng)用isUserInRole時(shí)引擎將調(diào)用security-role-ref到security-role的匹配。
          舉個(gè)例子:
          <security-role-ref>
           <role-name>FOO</role-name>
           <role-link>manager</role-link>
          </security-role-ref>
          當(dāng)一個(gè)用戶屬于“manager”角色是調(diào)用isUsesrInRole("FOO")返回true
           
          如果匹配一個(gè)security-role元素的security-role-ref沒有被定義,引擎必須找出一個(gè)與security-role列表不同的roel-name元素作為web應(yīng)用默認(rèn)的安全角色。但默認(rèn)的安全角色限制了變換角色名稱不需要重新編譯的機(jī)動(dòng)性。
          12.4 角色
          一個(gè)安全角色是一組用戶的邏輯名稱。當(dāng)應(yīng)用發(fā)布時(shí),角色就部署在web應(yīng)用的運(yùn)行時(shí)環(huán)境中了。在基于安全屬性的請求到來時(shí),servlet引擎就會執(zhí)行公共安全或程序級安全。安全請求在以下的一些情況中會產(chǎn)生:
          1)開發(fā)者給用戶群配置了一個(gè)安全角色。
          2)開發(fā)者把一個(gè)安全角色配置給一個(gè)安全域中的一個(gè)主要名稱。
          12.5 驗(yàn)證
          web客戶端可以用以下的一些機(jī)制驗(yàn)證用戶:
          .HTTP Basic Authentication
          .HTTP Digest Authentication
          .HTTPS Client Authentication
          .Form Based Authentication
          12.5.1 HTTP Basic Authentication
          HTTP Basic Authentication是基于用戶名和密碼的驗(yàn)證機(jī)制,是在HTTP/1.0規(guī)范中定義的。web服務(wù)要求客戶端驗(yàn)證用戶,web服務(wù)用一個(gè)realm字符串作為請求的一部分,用戶通過這個(gè)realm字符串被驗(yàn)證。realm字符串不會和任何安全域相關(guān)聯(lián)??蛻舳双@得用戶名稱和密碼發(fā)送到服務(wù)端。然后服務(wù)端用一個(gè)特殊的realm去驗(yàn)證該用戶。
          Basic Authentication 不是安全的驗(yàn)證協(xié)議。用戶的密碼是用base64編碼的,服務(wù)端是不能夠識別的。一些附加的安全措施可以被使用,這些協(xié)議有:HTTPS安全傳輸協(xié)議或網(wǎng)絡(luò)安全標(biāo)準(zhǔn)(如IPSEC協(xié)議、VPN策略)。
          12.5.2 HTTP Digest Authentication
          和HTTP Basic Authentication一樣,HTTP Digest Authentication 也是驗(yàn)證用戶名和密碼的。然而這種驗(yàn)證是把密碼加密傳輸?shù)模菳asic Authentication的base64編碼要安全的多。Digest Authentication 沒有被廣泛的運(yùn)用,建議servlet引擎支持這種驗(yàn)證,但不是必須的。
          12.5.3 Form Based Authentication
          web應(yīng)用部署描述文件包含登陸表單和錯(cuò)誤頁面。登陸表單必須包含用戶名和用戶密碼字段,這兩個(gè)字段必須以j_username和j_password命名。當(dāng)一個(gè)用戶要訪問一個(gè)被保護(hù)的資源時(shí),引擎就會驗(yàn)證該用戶信息,如果該用戶驗(yàn)證通過就會調(diào)用保護(hù)的資源,如果沒有驗(yàn)證通過,以下的步驟就會發(fā)生:
          1)登陸表單被送到客戶端,啟動(dòng)這個(gè)驗(yàn)證的URL路徑將被引擎保存。
          2)用戶被要求填寫用戶名和密碼
          3)客戶端重新post表單到服務(wù)端
          4)引擎嘗試著重新去驗(yàn)證該用戶的信息
          5)如果驗(yàn)證有失敗,響應(yīng)被設(shè)置為401的錯(cuò)誤頁面將被返回
          6)如果驗(yàn)證成功,如果該訪問的資源在一個(gè)授權(quán)角色中,將進(jìn)一步驗(yàn)證。
          7)如果用戶是授權(quán)用戶,客戶端將用保存的URL路徑重新定向到訪問的資源。
          發(fā)送到驗(yàn)證失敗的用戶的錯(cuò)誤頁面包含了失敗的信息。
          Form Based Authentication 和 Basic Authentication 有一樣的弊端,密碼是用簡單的文本傳輸?shù)?,不能夠被服?wù)端驗(yàn)證。附加的一些協(xié)議可以增強(qiáng)這部分功能。如HTTPS傳輸協(xié)議,或網(wǎng)路安全標(biāo)準(zhǔn)(如IPSEC協(xié)議或VPN策略)。
          12.5.3.1 登陸表單的一些注意事項(xiàng)
          登陸的表單和跟蹤session的URL實(shí)現(xiàn)上是有限制的。
          登陸表單只能在cookies或SSL跟蹤session的方式下才能使用。
          登陸表單要進(jìn)行驗(yàn)證的話,表單的action就必須為j_security_check。這個(gè)約束使得登陸表單訪問的資源沒有問題,也避免了把表單外的字段提交進(jìn)請求中。
          在HTML頁面中登陸表單的一個(gè)例子如下:
          <form method="POST" action="j_security_check" >
           <input type="text" name="j_username">
           <input type="password" name="j_password">
          </form>
          當(dāng)?shù)顷懕韱我驗(yàn)镠TTP請求被調(diào)用時(shí),原始的請求參數(shù)必須被引擎存儲,在驗(yàn)證成功后重新定向請求的資源。
          如果用登陸表單的用戶被驗(yàn)證通過,創(chuàng)建了一個(gè)session,當(dāng)session超時(shí)或調(diào)用了失效方法,使得登陸者推出了。后續(xù)來的請求就必須重新對用戶進(jìn)行驗(yàn)證。
          12.5.4 HTTPS Client Authentication
          用HTTPS驗(yàn)證用戶是很強(qiáng)的驗(yàn)證機(jī)制。這個(gè)驗(yàn)證需要用戶擁有一個(gè)公共鑰匙(PKC)。servlet引擎不需要支持HTTPS協(xié)議。
          12.6 驗(yàn)證信息的跟蹤
          基本的身份驗(yàn)證實(shí)在運(yùn)行時(shí)環(huán)境中進(jìn)行的:
          1)確認(rèn)一個(gè)登陸驗(yàn)證機(jī)制或策略已經(jīng)配置在web應(yīng)用中。
          2)把需驗(yàn)證的信息發(fā)往一個(gè)容器中的所有應(yīng)用。
          3)當(dāng)一個(gè)安全域被刪除時(shí),用戶的請求就需要重新驗(yàn)證。
           
          第十三章 部署描述文件
          13.1 部署描述元素
          部署描述文件中的所有元素都要被所有的servlet引擎支持。配置類型有下面的幾種:
          .ServletContext Init Parameteres
          .Session Configuration
          .Servlet Declaration
          .Servlet Mapping
          .Application Lifecycle Listener classes
          .Filter Dfinitions and Filter Mappings
          .MIME Type Mappings
          .Error Pages
          當(dāng)servlet 引擎是實(shí)現(xiàn)了J2EE規(guī)范的一部分的時(shí)候,安全信息才有必要在部署描述文件中定義。
          部署描述文件不光光只支持servlet規(guī)范,在部署描述文件為了適應(yīng)web應(yīng)用的需求增加了其他的部屬描述元素。如:
          .taglib
          .用于查找JNDI對象的一些元素(env-entry,ejb-ref,ejb-local-ref,resource-ref,resource-env-ref)
           
          13.2 處理部屬描述文件的規(guī)則
          本節(jié)主要講一下web容器訪問部屬描述文件的幾種規(guī)則。
          .web容器應(yīng)該忽略部屬描述文件中數(shù)據(jù)的開始空字符和最后的空字符。
          .web容器應(yīng)該有一個(gè)廣泛的選項(xiàng)用戶檢查web應(yīng)用的有效性。如檢查web應(yīng)用是否包含部署描述文件,部屬描述文件結(jié)構(gòu)是否正確。部署描述中應(yīng)該有語義檢查,如:安全規(guī)則有同樣的名字,應(yīng)該報(bào)錯(cuò)等等。
          .部署描述中的URI是假定在URL解碼表單中的
          .引擎必須正確解釋部屬文件中的路徑,如:路徑'/a/../b'必須解釋為'/b',因?yàn)槁窂绞且?..'開始的路徑在部署描述中是無效的。
          .調(diào)用資源的URI與WAR的根目錄關(guān)聯(lián),以‘/’開頭
          .在一個(gè)元素中,如果它的顯示值是一個(gè)列表,則這個(gè)列表將可能會報(bào)錯(cuò)
          13.2.1 DOCTYPE
          所有2.3版本的部屬描述文件的DOCTYPE必須是:
          <!DOCTYPE web-app PUBLIC "-//sun Microsystems, inc.//DTD Web Application 2.3//EN" "13.3 DTD
          web應(yīng)用的部署描述文件DTD如下:
          <!--
           web-app 元素是部署描述的根元素
          -->
          <!ELEMENT web-app(icon?,display-name?,description?,distributable?,context-param*,filter*,filter-mapping*,listener*,servlet*,servlet-mapping*,session-config?,mime-mapping*,welcome-file-list?,error-page*,taglib*,resource-env-ref*,resource-ref*,security-constraint*,login-config?,security-role*,env-entry*,ejb-ref*,ejb-local-ref*)>
          <!--
          Auth-constraint 元素定義了可以訪問資源列表的用戶角色。Role-name可以作為security-role元素的子元素出現(xiàn)也可以以role-name"*"出現(xiàn)表示所有的角色,如果*和role-name都出現(xiàn)了,引擎將解釋這個(gè)資源可以被所有角色使用。如果沒有定義角色,用戶就不能夠訪問定義的資源。
          Used in :security-constraint
          -->
          <!ELEMENT auth-constraint (description?,role-name*)>
          <!--
          Auth-method 元素是配置web應(yīng)用的安全機(jī)制的,是訪問被保護(hù)資源的先決條件。用戶必須用這個(gè)驗(yàn)證機(jī)制驗(yàn)證。這個(gè)元素Value值有“BASIC”,“DIGEST”,“FORM”或“CLIENT-CERT”
          Userd in : login-config
          -->
          <!ELEMENT auth-method(#PCDATA)>
          <!--
          Context-param元素包含了servlet context初始化的參數(shù)
          Used in :web-app
          -->
          <!ELEMENT context-param(param-name,param-value,description?)>
          <!--
          description元素用于對父元素進(jìn)行說明,description元素可以包含任何說明信息。當(dāng)父元素被工具訪問時(shí)這些說明就會顯示。
          Used in :auth-contraint,context-param,ejb-local-ref,ejb-ref,env-entry,filter,init-param,resource-env-ref,resource-ref,ren-as,security-role,security-role-ref,servlet,user-data-constraint,web-app,web-resource-collection
          -->
          <!ELEMENT description(#PCDATA)>
          <!--
          Display-name元素是一個(gè)簡稱,被調(diào)用的工具顯示,這個(gè)簡稱不必是唯一的
          Used in: filter,security-constraint,sevlet,web-app
          例如:
          <display-name>Employee self Service </display-name>
          -->
          <!ELEMENT display-name(#PCDATA)>
          <!--
          Distributable 元素,這個(gè)元素出現(xiàn)在部署描述中,說明該應(yīng)用可以部署在分布式servlet引擎中。
          Used in :web-app
          -->
          <!ELEMENT distributable EMPTY>
          <!--
          Ejb-link 元素用在ejb-ref 或ejb-local-ref元素中,去指定EJB關(guān)聯(lián)的一個(gè)enterprise bean.
          Ejb-link中的名字是一個(gè)關(guān)聯(lián)著enterprise bean的路徑 或者是目標(biāo)bean+一個(gè)以“#”開頭的路徑。一個(gè)ejb-name可以對應(yīng)多個(gè)enterprise beans。
          Used in : ejb-local-ref,ejb-ref
          例如:
          <ejb-link>EmployeeRecord</ejb-link>
          <ejb-link>../products/product.jar#ProductEJB</ejb-link>
          -->
          <!ELEMENT ejb-link (#PCDAATA)>
          <!--
           ejb-local-ref 元素用于描述本地enterprise bean的home接口,描述由下面的部分組成:
          一個(gè)可選的描述
          與enterprise bean 相關(guān)的EJB名稱
          Enterprise bean 的類型
          Enterprise bean 的本地接口
          可選的ejb-link信息
          Used in: web-app
          -->
          <!ELEMENT ejb-local-ref (description?,ejb-ref-name,ejb-ref-type,local-home,local,ejb-link?)>
          <!--
          Ejb-ref 元素用于描述enterprise bean的home接口。描述由下面組成:
          一個(gè)可選描述
          與enterprise bean 相關(guān)的EJB名稱
          Enterprise bean 的類型
          Enterprise bean 的本地接口
          可選的ejb-link信息
          Used in:web-app
          -->
          <!ELEMENT ejb-ref(description?,ejb-ref-name,ejb-ref,type,home,remote,ejb-link?)>
          <!--
          Ejb-ref-name 元素包含一個(gè)EJB的名字,這個(gè)名字必須是唯一的;這個(gè)EJB是web應(yīng)用環(huán)境和關(guān)聯(lián)的java:comp/env context的入口。建議名字以“ejb/”開頭。
          Used in : ejb-local-ref,ejb-ref
          例如:
          <ejb-ref-name>ejb/Payroll</ejb-ref-name>
          -->
          <!ELEMENT ejb-ref-name(#PCDATA)>
          <!--
          Ejb-ref-type 元素包含enterprise bean的類型。Ejb-ref-type元素必須是下面的一種:
          <ejb-ref-type>Entity</ejb-ref-type>
          <ejb-ref-type>Session</ejb-ref-type>
          Used in :ejb-local-ref,ejb-ref
          -->
          <!ELEMENT ejb-ref-type(#PCDATA)>
          <!--
          Env-entry 元素包含了web應(yīng)用的環(huán)境入口的描述。描述包含一個(gè)可選的描述,一個(gè)環(huán)境入口的名稱,一個(gè)可選的value,如果value沒有被指定,在部署中必須提供。
          -->
          <!ELEMENT env-entry (description?,env-entry-name,env-entry-value?,env-entry-type)>
          <!--
           env-entry-name元素包含了web應(yīng)用環(huán)境入口的名稱,這個(gè)名稱是一個(gè)java:comp/env context關(guān)聯(lián)的JNDI名稱。名字必須是唯一的。
          例如:
          <env-entry-name>minAmount</env-entry-name>
          Used in: env-entry
          -->
          <!ELEMENT env-entry-name(#PCDATA)>
          <!--
          Env-entry-type 元素包含環(huán)境入口值的fully-qualified java類型,這是web應(yīng)用程序期望有的。
          Env-enry-type合法的類型如下:
          Java.lang.Boolean
          Java.lang.Byte
          Java.lang.Character
          Java.lang.String
          Java.lang.Short
          Java.lang.Integer
          Java.lang.Long
          Java.lang.Float
          Java.lang.Double
          Used in : env-entry
          -->
          <!ELEMENT env-entry-type(#PCDATA)>
          <!--
          Env-entry-value元素包含了web應(yīng)用環(huán)境入口的值,值必須是一個(gè)字符串。
          例如:
          <env-entry-value>100.00</env-entry-value>
          Used in : env-entry
          <!ELEMENT env-entry-value(#PCDATA)>
           
          <!--
          Error-code元素包含HTTP的一個(gè)錯(cuò)誤代碼,如:404
          Used in : error-page
          -->
          <!ELEMENT error-code(#PCDATA)>
          <!--
           error-page 元素包含一個(gè)錯(cuò)誤代碼映射或錯(cuò)誤類型資源的一個(gè)路徑
          Used in : web-app
          -->
          <!ELEMENT error-page((error-code | exception-type),location)>
          <!--
           exception-type 包含一個(gè)java exception 類型的類名稱
          Used in : error-page
          -->
          <!ELEMENT exception-type(#PCDATA)>
          <!--
           extension元素包含一個(gè)擴(kuò)展名。如“txt”
          Used in : mine-mapping
          -->
          <!ELEMENT extension (#PCDATA)>
          <!--
           filter被filter-mapping中的一個(gè)servlet或一個(gè)URL通過filter-name映射。filter在運(yùn)行時(shí)能夠通過FilterConfig接口訪問初始化的參數(shù)。
          Used in : web-app
          -->
          <!ELEMENT filter (icon?,filter-name,display-name?,description?,filter-class,init-param*)>
           
          <!--
           filter-class元素指明filter類.
          Used in :filter
          -->
          <!ELEMENT filtere-class(#PCDATA)>
          <!--
           引擎用filter-mapping去匹配請求的URI以及匹配的順序,引擎在把匹配的URI匹配一個(gè)servlet。
          Used in : web-app
          -->
          <!ELEMENT filter-mapping (Filter-name,(url-pattern | servlet-name))>
          <!--
           filtere-name元素表明了一個(gè)filter的邏輯名稱用于匹配用的。邏輯名稱必須唯一
          Used in : filter,filere-mapping
          -->
          <!ELEMENT filter-name (#PCDATA)>
          <!--
           form-error-page元素定義了當(dāng)?shù)顷懯∈钦{(diào)用的頁面。這個(gè)路徑以“/”開始
          Used in: form-login-config
          -->
          <!ELEMENT form-error-page (#PCDATA)>
          <!--
           form-login-config元素指定了登陸的錯(cuò)誤頁面,如果form不需要驗(yàn)證,這個(gè)元素將被忽略。
          Used in : login-config
          -->
          <!ELEMENT form-login-cofig (form-login-page,form-error-page)>
          <!--
           form-login-page 元素定義了登陸的頁面。路徑以“/”開頭
           used in :form-login-config
          -->
          <!ELEMENT form-login-page (#PCDATA)>
          <!--
           home元素包含了enterprise bean的home接口的名稱
          Used in :ejb-ref
          例如:
          <home>com.aardvark.payroll.PayrollHome</home>
          <!ELEMENT home (#PCDATA)>
          <!--
           http-method 包含了HTTP 方法(GET | POST |...)
          Used in:web-resource-collection
          -->
          <!ELEMENT http-method (#PCDATA)>
           
          <!--
           icon 元素包含small-icon 和large-icon元素,指明一個(gè)gif或jpeg的圖標(biāo)名稱
          Used in : filter,servlet,web-app
          -->
          <!ELEMENT icon (small-icon?,large-icon?)>
           
          <!--
           init-param元素包含了name/value的servlet的初始化參數(shù)
          Used in : filter,servlet
          -->
          <!ELEMETN init-param (param-name,param-value,description?)>
          <!--
           jsp-file 元素 包含了一個(gè)以“/”開頭JSP文件的全名。
          Used in : servlet
          -->
          <!ELEMENT jsp-file (#PCDATA)>
          <!--
           large-icon 元素包含一個(gè)32*32的圖標(biāo)文件名稱。圖片可以是jpeg或gif。
           used in :icon
          例如:
          <large-icon>employee-service-icon32*32.jsp</large-icon>
          -->
          <!ELEMENT large-icon (#PCDATA)>
           
          <!--
           listener 元素對應(yīng)著listener bean
          Used in : web-app
          -->
          <!ELEMENT listener (listener-class)>
          <!--
           listener-class 元素,元素值是監(jiān)聽類的類名。
          Used in : listener
          -->
          <!ELEMENT listener-class (#PCDATA)>
          <!--
           load-on-startup 元素指明了這個(gè)servlet在web啟動(dòng)時(shí)是否必須裝入(調(diào)用servlet的init()方法)。這個(gè)內(nèi)容是可選的,但有值時(shí)必須是個(gè)整數(shù),如果是負(fù)數(shù),引擎可以選擇在任何時(shí)候裝載該servlet,如果是整數(shù)或0,引擎就必須在web應(yīng)用啟動(dòng)時(shí)裝入該servlet。數(shù)字越小越被優(yōu)先裝入。如果值一樣,引擎可以自由選擇裝入的順序。
          Used in : servlet
          -->
          <!ELEMENT load-on-startup (#PCDATA)>
          <!--
           local元素包含了enterprise bean的local接口
          Used in : ejb-local-ref
          -->
          <!ELEMENT local (#PCDATA)>
          <!--
           local-home元素包含了enterprise bean的本地home接口
          Used in : ejb-local-ref
          -->
          <!ELEMENT local-home (#PCDATA)>
           
          <!--
           location 元素包含與web應(yīng)用根目錄關(guān)聯(lián)的資源,值必須以‘/’開頭
          Used in : error-page
          -->
          <!ELEMENT location (#PCDATA)>
          <!--
           login-config 元素用于配置驗(yàn)證的方法的。
          Used in :web-app
          -->
          <!ELEMENT login-conifg (auth-method?,realm-name?,form-login-config?)>
           
          <!--
           mime-mapping 元素定義了擴(kuò)展名和mime類型的映射關(guān)系。
          Used in :web-app
          -->
          <!ELEMENT mime-mapping (extension,mime-type)>
           
          <!--
           mime-type 元素包含了mime類型,如“text/plain”
          Used in : mime-mapping
          -->
          <!ELEMENT mime-type (#PCDATA)>
          <!--
           param-name 元素包含參數(shù)的名稱,參數(shù)名必須唯一。
          Used in : context-param,init-param
          -->
          <!ELEMENT param-name (#PCDATA)>
           
          <!--
           param-value元素包含了參數(shù)的值
          Used in : context-param,init-param
          -->
          <!ELEMENT param-value (#PCDATA)>
           
          <!--
           realm-name 元素用于HTTP Basic 驗(yàn)證中
          Used in : login-config
          -->
          <!ELEMENT realm-name (#PCDATA)>
           
          <!--
           remote 元素包含了enterprise bean 的remote接口
          Used in : ejb-ref
          例如:
           <remote>com.wombat.empl.EmployeeService</remote>
          -->
          <!ELEMENT remote (#PCDATA)>
           
          <!--
           res-auth 元素表明是web應(yīng)用代碼控制資源,還是引擎控制資源。該元素的值只能是以下的一種
              <res-auth>Application</res-auth>
              <res-auth>Container</res-auth>
          Used in : resource-ref
          -->
          <!ELEMENT res-auth (#PCDATA)>
           
          <!--
           res-ref-name 元素指明了資源管理器(連接工廠)的名稱,這個(gè)名稱是和java:comp/env cocntext關(guān)聯(lián)的JNDI名稱。該名稱必須是唯一的。
          Used in:resource-ref
          -->
          <!ELEMENT res-ref-name (#PCDATA)>
           
          <!--
           res-sharing-scope 元素表明了從資源管理器連接工廠獲得的連接是否可以被共享。值必須是下面的一種:
           <res-sharing-scope>Shareable</res-sharing-scope>
           <res-sharing-scope>Unshareable</res-sharing-scope>
          默認(rèn)的值是Shareable
          Used in : resource-ref
          <!ELEMENT ref-sharing-scope (#PCDATA)>
           
          <!--
           res-type 元素描述了資源的數(shù)據(jù)類型。
          Used in : resource-ref
          -->
          <!ELEMENT res-type (#PCDATA)>
           
          <!--
           resource-env-ref 元素描述了與web應(yīng)用管理對象相關(guān)的資源。包含一個(gè)可選的描述,一個(gè)資源環(huán)境名稱,一個(gè)環(huán)境資源類型。
          Used in :web-app
          例如:
          <resource-env-ref>
           <resource-env-ref-name>jms/StockQueue</resource-env-ref-name>
           <resource-env-type>javax.jms/Queue</resource-env-ref-type>
          </resource-env-ref>
          -->
          <!ELEMENT resource-env-ref (description?,resource-env-ref-name,resource-env-ref-type)>
           
          <!--
           resource-env-ref-name元素一定一個(gè)環(huán)境資源名稱,這個(gè)名字是與java:comp/env context關(guān)聯(lián)的JNDI名稱,必須以唯一的。
          Used in : resource-env-ref
          -->
          <!ELEMENT resource-env-ref-name (#PCDATA)>
           
          <!--
           resource-env-ref-type元素定義了環(huán)境資源的類型,是一個(gè)java類或接口的全名。
          Used in: resource-env-ref
          -->
          <!ELEMENT resource-env-ref-type (#PCDATA)>
           
          <!--
             resource-ref 元素包含web應(yīng)用涉及的外部資源的描述。它有一個(gè)可選的描述,一個(gè)資源管理連接工廠的名稱,一個(gè)資源管理連接工廠的類型id,一個(gè)驗(yàn)證類型(Application 或 Container),和一個(gè)可選的連接共享的選項(xiàng)(Shareale 或 Unshareable)
          Used in : web-app
          例如:
          <resource-ref>
          <res-ref-name>jdbc/EmployeeApppDB</res-ref-name>
          <res-type>javax.sql.DataSource</res-type>
          <res-auth>Container</res-auth>
          <res-sharing-scope>Shareable</res-sharing-scope>
          </resource-ref>
          -->
          <!ELEMENT resource-ref (description?,res-ref-name,res-type,res-auth,res-sharing-scope?)>
           
          <!--
           role-link 元素是與安全角色相關(guān)的。Role-link元素必須包含一個(gè)在security-role元素中定義的安全角色的名稱。
          Used in: security-role-ref
          -->
          <!ELEMENT role-link (#PCDATA)>
           
          <!--
           role-name 元素包含一個(gè)安全角色的名稱,名稱必須遵守NMTOKEN規(guī)則。
          Used in : auth-constraint,run-as,security-role,security-role-ref
          -->
          <!ELEMENT role-name (#PCDATA)>
           
          <!--
           run-as 元素包含一個(gè)可選的描述,和一個(gè)安全角色的名稱。
          Used in : servlet
          -->
          <!ELEMENT run-as (description?,role-name)>
           
          <!--
           security-constraint元素用于安全約束與一個(gè)或多個(gè)web資源相關(guān)聯(lián)。
          Used in :web-app
          -->
          <!ELEMENT security-constraint (display-name?,web-resource-collection+,auth-constraint?,user-data-constraint?)>
           
          <!--
           security-role元素包含安全角色的定義,它由一個(gè)可選的安全角色的描述,一個(gè)安全角色名稱組成。
          Used in : web-app
          例如:
          <security-role>
          <description>
             this role includes all employees who are authorized to access the employee service application.
          </description>
          <role-name>employee</role-name>
          </security-role>
          -->
          <!ELEMENT security-role (description?,role-name)>
           
          <!--
           security-role-ref 元素包含一個(gè)可選的描述,一個(gè)調(diào)用代碼中的安全角色名稱,一個(gè)可選的安全角色連接。如果安全角色沒有被指定,開發(fā)者必須選擇一個(gè)適當(dāng)?shù)陌踩巧_@個(gè)role-name元素的值必須是EJBConteext.isCallerInRole(String roleName)或HttpServletRequest.isUserInRole(String role)中的參數(shù)。
          Used in :servlet
          -->
          <!ELEMENT security-role-ref (description?,role-name,role-link?)>
           
          <!--
           servlet 元素包含一個(gè)servlet的數(shù)據(jù)描述。如果load-on-startup元素中指定了一個(gè)jsp文件,該JSP將被裝入。
          Used in : web-app
          <!ELEMENT servlet (icon?,servlet-name,display-name?,description?,(servlet-class|jsp-file),init-param*,load-on-startup?,run-as?,security-role-ref*)>
           
          <!--
           servlet-class元素包含一個(gè)全名的servlet類名稱。
          Used in : servlet
          -->
          <!ELEMENT servlet-class (#PCDATA)>
           
          <!--
           servlet-mapping元素定義了一個(gè)servlet和url的關(guān)聯(lián)
          Used in : web-app
          -->
          <!ELEMENT servlet-mapping (servlet-name,url-pattern)>
           
          <!--
           servlet-name元素包含servlet的名稱,名稱是唯一的。
          Used in : filter-mapping,servlet,servlet-mapping
          -->
          <!ELEMENT servlet-name (#PCDATA)>
           
          <!--
           session-config 元素定義了session參數(shù)
          Used in : web-app
          -->
          <!ELEMENT session-config (session-timeout?)>
           
          <!--
           session-timeout 元素定義了一個(gè)默認(rèn)的會話超時(shí)的時(shí)間,使用于web應(yīng)用中的所有會話。時(shí)間必須是用分鐘的數(shù)值表示。
          如果timeout是0或負(fù)數(shù),引擎將確保會話永遠(yuǎn)不會超時(shí)。
          Used in : session-config
          -->
          <!ELEMENT session-timeout (#PCDATA)>
           
          <!--
           small-icon 元素包含一個(gè)16*16圖標(biāo)文件的名稱。
          Used in : icon
          例如:
           <small-icon>employee-service-icon16*16.jpg</small-icon>
          -->
          <!ELEMENT small-icon (#pCDATA)>
           
           taglib 元素用于描述JSP tag 庫。
          Used in : web-app
          -->
          <!ELEMENT taglib (taglib-uri,taglib-location)>
           
          <!--
           taglib-location 元素包含一個(gè)資源定位,為tag庫找到tag描述文件
          Used in:taglib
          -->
          <!ELEMENT taglib-location (#PCDATA)>
           
          <!--
           taglib-uri元素描述了一個(gè)URI
          Used in: taglib
          -->
          <!ELEMENT taglib-uri (#PCDATA)>
           
          <!--
           transport-guarantee元素指定了客戶端和服務(wù)端的通信關(guān)系,有NONE,INTEGRAL,CONFIDENTIAL。NONE表示著應(yīng)用不需要任何傳輸保障。INTEGRAL表示著在數(shù)據(jù)在客戶端到服務(wù)端的過程中不能有任何改變。CONFIDENTIAL表示在傳輸過程中防止其他傳輸內(nèi)容的干擾。在使用SSl時(shí)常用的就INTEGRAL或CONFIDENTIL。
          Used in : user-data-constraint
          <!ELEMENT transport-guarantee (#PCDATA)>
           
          <!--
           url-pattern 元素包含映射的url。必須符合11.2章中servlet API描述的規(guī)則。
          Used in:filter-mapping,servlet-mapping,web-resource-collection
          -->
          <!ELEMENT url-pattern (#PCDATA)>
           
          <!--
           user-data-constraint元素用于表明數(shù)據(jù)在客戶端到服務(wù)器端是怎么保護(hù)的。
          Used in :security-constraint
          -->
          <!ELEMENT user-data-constraint (description?,transport-guarantee)>
           
          <!--
           web-resource-collection元素用于web應(yīng)用中安全限制的資源被那些方法使用,如果沒有指定,就可以被web用的所有方法調(diào)用。
          Used in:security-constraint
          -->
          <!ELEMENT web-resource-collection (web-resource-name,description?,url-pattern*,http-method*)>
           
          <!--
           web-resource-name 包含一個(gè)web資源集合的名稱
          Used in:web-resource-collection
          -->
          <!ELEMENT web-resource-name (#PCDATA)>
           
          <!--
           welcome-file元素包含了web應(yīng)用中默認(rèn)的訪問文件,如index.html
          Used in:welcome-file-list
          -->
          <!ELEMENT welcome-file (#PCDATA)>
           
          <!--
           welcome-file-list包含welcome-file的列表
          Used in:web-app
          -->
          <!ELEMENT welcome-file-list (welcome-file+)>
          <!--
           ID機(jī)制可以增加額外的部署信息,不允許加一個(gè)非標(biāo)準(zhǔn)的元素到標(biāo)準(zhǔn)的部署描述中
          -->
          <!ATTLIST auth-constraint id ID #IMPLIED>
          <!ATTLIST auth-method id ID #IMPLIED>
          <!ATTLIST context-param id ID #IMPLIED>
          <!ATTLIST description id ID #IMPLIED>
          <!ATTLIST display-name id ID #IMPLIED>
          <!ATTLIST ejb-link id ID #IMPLIED>
          <!ATTLIST ejb-local-ref id ID #IMPLIED>
          <!ATTLIST ejb-ref  id ID #IMPLIED>
          <!ATTLIST ejb-ref-name id ID #IMPLIED>
          <!ATTLIST ejb-ref-type id ID #IMPLIED>
          <!ATTLIST env-entry id ID #IMPLIED>
          <!ATTLIST env-entry-name id ID #IMPLIED>
          <!ATTLIST env-entry-type id ID #IMPLIED>
          <!ATTLIST env-enry-value id ID #IMPLIED>
          <!ATTLIST error-code id ID #IMPLIED>
          <!ATTLIST error-page id ID #IMPLIED>
          <!ATTLIST exception-type id ID #IMPLIED>
          <!ATTLIST extension id ID #IMPLIED>
          <!ATTLIST filter id ID #IMPLIED>
          <!ATTLIST filter-class id ID #IMPLIED>
          <!ATTLIST filtere-mapping id ID #IMPLIED>
          <!ATTLIST filter-name id ID #IMPLIED>
          <!ATTLIST form-error-page id ID #IMPLIED>
          <!ATTLIST form-login-config id ID #IMPLIED>
          <!ATTLIST form-login-page id ID #IMPLIED>
          <!ATTLIST home id ID #IMPLIED>
          <!ATTLIST http-method id ID #IMPLIED>
          <!ATTLIST icon id ID #IMPLIED>
          <!ATTLIST init-param id ID #IMPLIED>
          <!ATTLIST jsp-file id ID #IMPLIED>
          <!ATTLIST large-icon id ID #IMPLIED>
          <!ATTLIST listener id ID #IMPLIED>
          <!ATTLIST listener-class id ID #IMPLIED>
          <!ATTLIST load-on-startup id ID #IMPLIED>
          <!ATTLIST local id ID #IMPLIED>
          <!ATTLIST local-home id ID #IMPLIED>
          <!ATTLIST location id ID #IMPLIED>
          <!ATTLIST login-config id ID #IMPLIED>
          <!ATTLIST mime-mapping id ID #IMPLIED>
          <!ATTLIST mime-type id ID #IMPLIED>
          <!ATTLIST param-name id ID #IMPLIED>
          <!ATTLIST param-value id ID #IMPLIED>
          <!ATTLIST realm-name id ID #IMPLIED>
          <!ATTLIST remote id ID #IMPLIED>
          <!ATTLIST res-auth id ID #IMPLIED>
          <!ATTLIST res-ref-name id ID #IMPLIED>
          <!ATTLIST res-sharing-scope id ID #IMPLIED>
          <!ATTLIST res-type id ID #IMPLIED>
          <!ATTLIST resource-env-ref id ID #IMPLIED>
          <!ATTLIST resource-env-ref-name id ID #IMPLIED>
          <!ATTLIST resource-env-ref-type id ID #IMPLIED>
          <!ATTLIST resource-ref id ID #IMPLIED>
          <!ATTLIST role-link id ID #IMPLIED>
          <!ATTLIST role-name id ID #IMPLIED>
          <!ATTLIST run-as id ID #IMPLIED>
          <!ATTLIST security-constraint id ID #IMPLIED>
          <!ATTLIST security-role id ID #IMPLIED>
          <!ATTLIST security-role-ref id ID #IMPLIED>
          <!ATTLIST sevlet id ID #IMPLIED>
          <!ATTLIST servlet-class id ID #IMPLIED>
          <!ATTLIST servlet-mapping id ID #IMPLIED>
          <!ATTLIST servlet-name id ID #IMPLIED>
          <!ATTLIST session-config id ID #IMPLIED>
          <!ATTLIST session-timeout id ID #IMPLIED>
          <!ATTLIST small-icon id ID #IMPLIED>
          <!ATTLIST taglib id ID #IMPLIED>
          <!ATTLIST taglib-location id ID #IMPLIED>
          <!ATTLIST taglib-uri id ID #IMPLIED>
          <!ATTLIST transport-guarantee id ID #IMPLIED>
          <!ATTLIST rul-pattern id ID #IMPLIED>
          <!ATTLIST user-data-constraint id ID #IMPLIED>
          <!ATTLIST web-app id ID #IMPLIED>
          <!ATTLIST web-resource-collection id ID #IMPLIED>
          <!ATTLIST web-resource-name id ID #IMPLIED>
          <!ATTLIST welcome-file id ID #IMPLIED>
          <!ATTLIST welcome-file-list id ID #IMPLIED>
           
          13.4 例子
          13.4.1 基本的例子
          <!DOCTYPE web-app PUBLIC "-//Sun Mmicrosystems, Inc.//DTD Web Application 2.3//EN" "
          <web-app>
              <display-name>A Simple Application</display-name>
              <context-param>
                  <param-name>Webmaster</param-name>
                  <param-value>webmaster@mycorp.com</param-value>
             </context-param>
              <servlet>
                  <servlet-name>catalog</servlet-name>
                  <serrvlet-class>com.mycorp.Catalogservlet</servlet-class>
                  <init-param>
                      <param-name>catalog</param-name>
                      <param-value>Spring</param-value>
                  </init-param>
              </servlet>
              <servlet-mapping>
                  <servlet-name>catalog</servlet-name>
                  <url-pattern>/catalog/*</url-pattern>
              </servlet-mapping>
              <session-config>
                  <session-timeout>30</session-timeout>
              </session-config>
              <mime-mapping>
                  <extension>pdf</extension>
                  <mime-type>application/pdf</mime-type>
              </mime-mapping>
              <welcome-file-list>
                  <welcome-file>index.jsp</welcome-file>
                  <welcome-file>index.html</welcome-file>
                  <welcome-file>index.htm</welcome-file>
              </welcome-file-list>
              <error-page>
                  <error-code>404</error-code>
                  <location>/404.html</location>
              <error-page>
          </web-app>
           
          13.4.2 一個(gè)安全的例子
          <!DOCTYPE web-app PUBLIC "-//Sun Mmicrosystems, Inc.//DTD Web Application 2.3//EN" "
          <web-app>
              <display-name>A Secure Application</display-name>
              <security-role>
                  <role-name>manager</role-name>
              </security-role>
              <servlet>
                  <servlet-name>catalog</servlet-name>
                  <servlet-class>com.mycorp.CatalogServlet</servlet-class>
                  <init-param>
                      <param-name>catalog</param-name>
                      <param-value>Spring</param-value>
                  </init-param>
                  <security-role-ref>
                       <role-name>MGR</role-name>
                       <!-- 在代碼中用的角色名稱-->
                       <role-link>manager</role-link>
                  </security-role-ref>
              </servlet>
              <servlet-mapping>
                   <servlet-name>catalog</servlet-name>
                   <url-pattern>/catalog/*</url-pattern>
              </servlet-mapping>
              <security-constraint>
                  <web-resource-collection>
                      <web-resource-name>SalesInfo</web-resource-name>
                      <url-pattern>/salesinfo/*</url-pattern>
                      <http-method>GET</http-method>
                      <http-method>POST</http-method>
                  </web-resource-collection>
                  <auth-constraint>
                      <role-name>manager</role-name>
                  </auth-constraint>
                  <user-data-constraint>
                      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
                  </user-data-constraint>
              </security-constraint>
          </web-app>
           
          結(jié)尾:
          servlet2.3到此就結(jié)束了,至于對接口類的解釋。這里就不給與了。有興趣的朋友可以down一個(gè)servlet2.3的源碼包自己研究研究。

          Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1362756


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 原平市| 九龙县| 黑河市| 汝阳县| 平遥县| 阳东县| 大荔县| 吉木萨尔县| 紫金县| 淮南市| 西安市| 彰化市| 蛟河市| 禹城市| 南靖县| 原阳县| 德兴市| 乌拉特中旗| 泽州县| 永昌县| 香格里拉县| 涿州市| 贵州省| 定兴县| 乐至县| 新民市| 三穗县| 象山县| 革吉县| 常熟市| 巴塘县| 青龙| 肥西县| 云阳县| 云南省| 鄂温| 黔南| 新疆| 吉木萨尔县| 湘潭市| 麻栗坡县|