比如:在網上書店應用中,從一個客戶開始購物,到最后結賬,整個過程是一個Session. Servlet API中定義了javax.servlet.http.HttpSession接口,Servlet容器必須實現這一接口。當一個Session開始時,Servlet容器將創建一個HttpSession對象,在HttpSession對象中可以存放客戶狀態的信息。Servelt容器為HttpSession分配一個唯一標識符,稱為Session ID.Servlet容器把Session ID作為Cookie保存在客戶的瀏覽器中。每次客戶發出HTTP請求時,Servlet容器可以從HttpRequest對象中讀取Session ID,然后根據SessionID找到相應的HttpSession對象,從而獲取客戶的狀態信息。 HttpSession接口中的方法: getId():返回Session的ID; invalidate():使當前的Session失效,Servlet容器會釋放HttpSession對象占用的資源。 setAttribute(String name,Object value):將一對name/Value屬性保存在HttpSession對象中 getAttribut(String name):根據name參數返回保存在HttpSession對象的屬性值。 getAttributeNames():以數組的方式HttpSession對象中所有的屬性名。 isNew():判斷是否是新創建的Session,如果是新創建的Session,返回true,否則返回false setMaxInactiveInterval():設定一個Session可以處于不活動狀態的最大時間間隔,以秒為單位。如果超過這個時間。Session自動失效,如果設置為負數,表示不限制Session付出與不活動狀態的時間。 getMaxInactiveInterval()讀取當前Sessions可以處于不活動狀態的最大時間間隔。 在Java Servlet API中提出了跟蹤Session的另一種機制,如果客戶瀏覽器不支持Cookie,Servlet容器可以重寫客戶請求的URL,吧Session ID添加到URL信息中。 HttpServletResponse接口提供了重寫URL的方法: public java.lang.String encodeURL(java.lang.String url) 該方法的實現機制為: 先判斷當前的Web組件是否啟用Session,如果沒有啟用Session,例如在JSP中聲明 <%@ page session="false"%>或者已經執行了session.invalidate()方法,那么直接返回參數URL 再判斷客戶瀏覽器是否支持Cookie,如果支持Cookie,就直接返回參數URL;如果不支持,就在參數URL中加入Session ID信息,然后返回修改后的URL. String username1 = ""; (username1 為自定義的字段,從數據庫中取出值后放到里面) request.getSession().setAttribute("username",username1); 從request里得到session在把值傳進去,不過這種方法可以將從數據庫里取得的數據用session顯示于頁面,但當在頁面點擊按鈕產生別的action的時候,取出來顯示在頁面的數據就都沒了,原來是request的生命周期是一個請求,當另外一個請求發生時,原來action中的request的值沒重置了,也就是說原來的數據都沒了,所以在頁面也不會顯示.這時候要將原來action中的request.getSession().setAttribute("username",username1); 改為HttpSession session = request.getSession(); session.setAttribute("username",username1);這時候傳到頁面的生命周期就是一個會話,即使你在頁面有別的請求,但session中的值依然存在.
本文檔提供關于Tomcat的基礎信息.主要內容如下:Tomcat二進制版本安裝與Tomcat相關的腳本的主要內容與server.xml相關的主要內容,Tomcat的主要配置文件如何設置Tomcat與宿主web服務器一起工作的說明如何應用Tomcat配置一個現實中的web站點希望此文檔足以使新用戶可以開始使用Tomcat.如找不到某方面的內容請(按以下順序)查找Tomcat faq查找Tomcat包清單向Tomcat用戶郵件列表發出問題如此疑問的答案不存在,我們鼓勵把對疑問的解答放入Tomcat faq或此文檔.如對此文檔有意見或建議,請發送到Tomcat的郵件列表.Getting StartedTomcat是一個帶有jsp環境的servlet容器.servlet容器是一個根據用戶的行為可以管理和激活servlet的運行時的shell.粗略地可以將servlet容器分為如下幾類:獨立的servlet容器內置有web服務器的一部分.指當使用基于Java的web服務器的情形,例如servlet容器是JavaWebServer的一個部分. 獨立的servlet容器是Tomcat的默認模式.大多數的web服務器并非基于Java,因此,我們可以得出如下兩種容器的模式.進程內的servlet容器servlet容器作為web服務器的插件和Java容器的實現.Web服務器插件在內部地址空間打開一個JVM(java virtual machine)使Java容器得以在內部運行.如有某個需要調用servlet的請求,,插件將取得對此請求的控制并將他傳遞(使用JNI)給Java容器.進程內容器對于多線程,單進程的服務器非常合適并且提供很好的運行速度,但伸縮性有所不足.進程外的servlet容器servlet容器運行于web服務器之外的地址空間且作為web服務器的插件和Java容器的實現的結合.web服務器插件和Java容器 JVM使用IPC機制(通常是TCP/IP)進行通訊.當一個調用servlet的請求到達時,插件將取得對此請求的控制并將其傳遞(使用IPC等)給Java容器,進程外容器的反應時間或進程外容器引擎不如進程內容器,但進程外容器引擎在許多其他可比的范圍內更好(伸縮性,穩定性等).Tomcat既可作為獨立的容器(主要是用于開發與調試)又可作為對現有服務器的附加(當前支持Apache,IIS和Netscape服務器).即任何時候配置Tomcat你都必須決定如何應用他,如選擇第二或第三種模式,你還需要安裝一個web服務器接口.Tomcat與Jserv有何區別?Tomcat是Jserv嗎?這是個常見的誤解.Jserv是Servlet API2.0兼容并與Apache一起使用的容器.Tomcat是一個完全重寫的并與Servlet API2.2和JSP1.1兼容的容器.Tomcat使用了一些為Jserv而寫的代碼,特別是Jserv的Apache接口,但這是唯一的相同之處.怎樣安裝Tomcat的二進制版本?非常簡單,只需:下載 zip/tar.gz 任何壓縮文件,從http://jakarta.apche.org/download/binindex.html處.解壓縮此文件到某目錄(如:foo).將會生成一子目錄,名為”tomcat”.轉換到”tomcat”目錄設置一新的環境變量(TOMCAT_HOME)指向你安裝的tomcat的目錄WIN32平臺,鍵入:“set TOMCAT_HOME=foo\tomcat”Unix平臺:如是bash/sh環境, 鍵入:”TOMCAT_HOME=foo/tomcat;export TOMCAT_HOME”如是tcsh環境, 鍵入:”setenv TOMCAT_HOME foo/tomcat”設置環境變量JAVA_HOME指向你JDK的目錄,然后添加JAVA解釋器到你的PATH環境變量.好了!現在可以運行TOMCAT并作為一個獨立的Servlet容器(模式一)啟動與關閉Tomcat使用”bin”目錄中的腳本啟動與關閉Tomcat.啟動:uinx:bin/startup.shwin32:bin\startup關閉:unix:bin/shutdown.shwin32:bin\shutdownTomcat目錄結構假設你已將Tomcat解壓,你已得到下列目錄結構:目錄名--描述 bin 包含啟動/關閉腳本 conf 包含不同的配置文件,包括 server.xml(Tomcat的主要配置文件)和為不同的Tomcat配置的web應用設置缺省值的文件web.xmldoc包含各種Tomcat文檔 lib 包含Tomcat使用的jar文件.unix平臺此目錄下的任何文件都被加到Tomcat的classpath中 logs Tomcat擺放日志文件的地方 src ServletAPI源文件.先別高興,這些只有些必須在Servlet容器內實現的空接口和抽象類 webapps 包含web項目示例 此外你可以Tomcat會創建如下目錄:workTomcat自動生成,放置Tomcat運行時的臨時文件(如編譯后的JSP文件).如在Tomcat運行時刪除此目錄.JSP頁面將不能運行.classes你可以創建此目錄來添加一些附加的類到類路徑中.任何你加到此目錄中的類都可在Tomcat的類路徑中找到自身.Tomcat的腳本Tomcat是一個Java程序,因此在設置好幾個環境變量后即可用命令行的方式運行.然而設置Tomcat使用的每個環境變量和如下的命令行參數乏味且易錯.因此,Tomcat開發組提供了一些腳本使啟動和關閉Tomcat變得輕松.注意:這些腳本僅僅是個便利的方法去啟動和關閉Tomcat.你可修改他們來定制CLASSPATH,環境變量如PATH,LD_LIBRARY_PATH,等等,只要是生成一個正確的命令行即可.這些腳本是什么呢?下表列出對一般用戶最重要的腳本.tomcat 主腳本.設置合適的環境變量,包括CLASSPATH,TOMCAT_HOME和JAVA_HOME和用適合的命令行參數啟動Tomcat startup 在后臺啟動Tomcat.”tomcat start”命令的替換方式 shutdown 關閉Tomcat.”tomcat stop”命令的替換方式 對用戶最重要的腳本是tomcat(tomcat.bat/tomcat.sh).其他Tomcat相關的腳本作為一個簡單的面向單任務的指向Tomcat腳本(設置不同的命令行參數等)的入口.仔細考察tomcat.bat/tomcat.sh,它按以下步驟運行:在Unix下的步驟:如未指定,推測 TOMCAT_HOME如未指定,推測 JAVA_HOME設置CLASS_PATH包含:1.${TOMCAT_HOME}/classes目錄(如果存在)2.${TOMCAT_HOME}/lib的一切內容3.${JAVA_HOME}/lib/tools.jar(此jar文件包含工具javac,我們需要javac處理jsp文件.運行帶有設定Java環境變量的命令行參數的java命令,調入tomcat.home,和org.apache.tomcat.startup.Tomcat 作為啟始類.同時也傳遞命令行參數到org.apache.tomcat.startup.Tomcat ,例如:執行start/stop/run 等的操作此Tomcat進程使用指向server.xml的路徑,例如server.xml放置于etc/server_1.xml并且用戶意圖在后臺啟動apache,鍵 入如下命令行:bin/tomcat.sh start ?f /etc/server_1.xml在Win32下的步驟:(略)由此可見,win32版的tomcat.bat與Unix版的幾乎一致.尤其在它不推測TOMCAT_HOME和JAVA_HOME的值,并且不將所有的jar文件放入類路徑中.Tomcat的配置文件Tomcat的配置基于兩個配置文件:1.server.xml - Tomcat的全局配置文件2.web.xml - 在Tomcat中配置不同的關系環境這一部分將講述如何使用這些文件.我們不會包含web.xml的內部機制,這些內部機制深入到了Servlet API的細節,因此,我們將討論涵蓋servler.xml內容及web.xml在Tomcat關系環境中的用法.server.xmlserver.xml是Tomcat的主配置文件.完成兩個目標:1 提供Tomcat組件的初始配置.2 說明Tomcat的結構,含義,使得Tomcat通過實例化組件完成起動及構建自身, 如在server.xml所指定的下表描述server.xml種的重要元素: 元素及其描述 Serverserver.xml文件中最重要的元素.Server定義了一個Tomcat服務器.一般你不用對他擔心太多.Server元素能包含Logger和ContextManager元素類型Logger此元素定義一個Logger對象,每個Logger都有一個名字去標識,也有一個紀錄Logger的輸出和冗余級別(描述此日志級別)和包含日志文件的路徑.通常有servlet的Logger(ServletContext.log()處),JSP和Tomcat運行時的Logger.ContextManagerContextManager說明一套ContextInterceptor, RequestInterceptor , Context和他們的Connectors的配置及結構.ContextManager有幾個隨同提供的特性:1. 用來紀錄調試信息的調試級別 2. webapps/,conf/,logs/和所有已定義的環境的基本位置.用來使Tomcat可以在TOMCAT_HOME外的其他目錄啟動. 3. 工作目錄的名字ContextInterceptor&RequestInterceptor這些偵聽器(interceptors)偵聽具體發生在ContextManager中的事件.例如,ContextInterceptor偵聽Tomcat的啟動及終止事件,RequestInterceptor監視在它服務過程中用戶請求需要通過的不同階段.Tomcat的管理員不必知道太多關于偵聽器的知識;另外,開發者應該知道這是如何在Tomcat中實現一個”全局”型的操作(例如安全性及每個請求日志)ConnectorConnector表示一個到用戶的聯接,不管是通過web服務器或直接到用戶瀏覽器(在一個獨立配置中).Connector負責管理Tomcat的工作線程和 讀/寫 連接到不同用戶的端口的 請求/響應.Connector的配置包含如下信息:1.句柄類2.句柄監聽的TCP/IP端口3.句柄服務器端口的TCP/IP的backlog.稍后我們將在此文檔中描述如何配置Connector.Context每個Context提供一個指向你放置你Web項目的Tomcat的下屬目錄。每個Context包含如下配置:1. Context放置的路徑,可以是與ContextManager主目錄相關的路徑.2.紀錄調試信息的調試級別3.可重載的標志.開發Servlet時,重載更改后的Servlet,這是一個非常便利的特性,你可以調試或用Tomcat測試新代碼而不用停止或重新啟動Tomcat.要打開重載,把reloadable設為真即可.這雖花費時間但可檢測所發生的變化;更重要的事,鑒于,在一個裝載類對象裝入一個新的servlet時,類裝載觸發器可能會擲出一些錯誤.為避免這些問題,你可以設置可重載為假,這將停止重載功能.從另一個目錄中啟動Tomcat作為缺省值將使用TOMCAT_HOME/conf/server.xml作為配置文件.缺省配置將使用TOMCT_HOME作為關系環境的基礎.使用 “-f/你的/目錄/server.xml”選項你可改變這種情況,使用另一個服務器配置文件和設置關系環境管理器的目錄屬性你需要在主目錄內設置以下幾個文件:? 一個 webapps/目錄(如果你已生成) ? 所有war文件獎杯界壓倒此目錄而且所有子目錄將作為關系環境添加.? conf/目錄 - 你可保存一個特殊的web.xml文件和其他配置文件? logs/ - 所有日志文件將代替TOMCAT_HOME/logs/紀錄到此目錄中? work/ - 關系環境的工作目錄如server.xml中的ContextManager.home屬性有關聯,將關聯到到當前工作目錄.web。xml關于web。xml和web項目結構(包括目錄服務及配置)的詳細描述可在Servlet API Spec的第9,10,14章中找到。然而有一個與Tomcat有關的小“特性“與web.xml有關。Tomcat可以讓用戶通過將缺省的web.xml放入conf目錄中來定義所有關系環境的web.xml的缺省值.建立一個新的關系環境時,Tomcat使用缺省的web.xml文件作為基本設置和應用項目特定的web.xml(放在應用項目的WEB-INF/web.xml文件)來覆蓋這些缺省值.設置Tomcat與Apache Web 服務器服務器到現在為止,我們未討論作為服務器擴展的Tomcat,只討論了作為獨立運行的服務器.但有一些問題需要說明:1. 當處理靜態頁面時,Tomcat不如Apache迅速.2. Tomcat不象Apache一樣可配置.3. Tomcat不象Apache一樣強壯.4. 有很多網站已在某一特定web server上投入了很長時間,例如,使用CGI腳本/Server API模組/perl/php…我們不能假設這些遺留下來的東西都會被丟棄.基于以上原因,一個現實的網站建議使用一個Web服務器,如Apache,為網站的靜態頁面請求提供服務,并使用Tomcat作為一個Servlet/JSP插件.我們不準備深入的討論每個不同的配置,我們將:1. 涵蓋Web服務器的基本行為2. 解釋需要何種配置3. 在Apache上的實例Web 服務器操作簡單說來,web服務器總是等待來自客戶端的HTTP請求。當請求到達時,服務器會提供一切必要的內容來滿足此請求。加入一個Servlet容器某種程度上會改變此行為。但服務器仍需處理如下因素:載入servlet容器接口庫并初始化(處理請求之前)。當收到一個請求時,檢查是否屬于某Servlet,如是,則接口庫接收此請求并處理。另一方面,接口庫需要知道他將服務某種請求,通常是基于請求的URL的某種模式和將此請求導向何處。當用戶想要設置使用虛擬主機的配置時,事情會變得更加復雜,或者想多個開發者在一個服務器上進行開發但使用不同的Servlet容器的JVMs。以下我們將討論這兩個問題。必需進行的配置應該考慮的是最明顯的配置是servlet URL具有對servlet容器中的servlet具有表示的責任。很明顯,你必須知道傳遞什么到Servlet容器。我們仍需提供附加的配置項目到web-server或servlet-container的結合體中.l 考慮到Tomcat進程是否可取得,我們仍需提供配置和Tomcat正在監聽的TCP/IP 主機名/端口號。l 需要告知web服務器接口庫的位置(因此我們可以在起始時裝入)l 需要設置接口內部信息如將日志記錄在何處和如何紀錄,等等。所有此類信息必須出現在web服務器配置里或被接口使用的私有配置文件中。下面將講述如何在Apache中如何實現這些配置。Apache上的實現這一部分演示如何配置Apache與Tomcat一起工作;并試圖解釋深入到可能會用到的配置規范。在jserv 安裝頁上可找到其他信息。
服務端不能主動連接客戶端,只能被動等待并答復客戶端請求。客戶端連接服務端,發出一個HTTP Request,服務端處理請求,并且返回一個HTTP Response給客戶端,本次HTTP Request-Response Cycle結束。
我們看到,HTTP協議本身并不能支持服務端保存客戶端的狀態信息。于是,Web Server中引入了session的概念,用來保存客戶端的狀態信息。
這里用一個形象的比喻來解釋session的工作方式。假設Web Server是一個商場的存包處,HTTP Request是一個顧客,第一次來到存包處,管理員把顧客的物品存放在某一個柜子里面(這個柜子就相當于Session),然后把一個號碼牌交給這個顧客,作為取包憑證(這個號碼牌就是Session ID)。顧客(HTTP Request)下一次來的時候,就要把號碼牌(Session ID)交給存包處(Web Server)的管理員。管理員根據號碼牌(Session ID)找到相應的柜子(Session),根據顧客(HTTP Request)的請求,Web Server可以取出、更換、添加柜子(Session)中的物品,Web Server也可以讓顧客(HTTP Request)的號碼牌和號碼牌對應的柜子(Session)失效。顧客(HTTP Request)的忘性很大,管理員在顧客回去的時候(HTTP Response)都要重新提醒顧客記住自己的號碼牌(Session ID)。這樣,顧客(HTTP Request)下次來的時候,就又帶著號碼牌回來了。
Session ID實際上是在客戶端和服務端之間通過HTTP Request和HTTP Response傳來傳去的。號碼牌(Session ID)必須包含在HTTP Request里面。關于HTTP Request的具體格式,請參見HTTP協議(http://www.w3.org/Protocols/)。這里只做一個簡單的介紹。
在Java Web Server(即Servlet/JSP Server)中,Session ID用jsessionid表示(請參見Servlet規范)。
HTTP Request一般由3部分組成:
(1)Request Line
這一行由HTTP Method(如GET或POST)、URL、和HTTP版本號組成。
例如,GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
GET http://www.google.com/search?q=Tomcat HTTP/1.1
POST http://www.google.com/search HTTP/1.1
GET http://www.somsite.com/menu.do;jsessionid=1001 HTTP/1.1
(2)Request Headers
這部分定義了一些重要的頭部信息,如,瀏覽器的種類,語言,類型。Request Headers中還可以包括Cookie的定義。例如:
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
Accept-Language: en-us
Cookie: jsessionid=1001
(3)Message Body
如果HTTP Method是GET,那么Message Body為空。
如果HTTP Method是POST,說明這個HTTP Request是submit一個HTML Form的結果,
那么Message Body為HTML Form里面定義的Input屬性。例如,
user=guest
password=guest
jsessionid=1001
主意,如果把HTML Form元素的Method屬性改為GET。那么,Message Body為空,所有的Input屬性都會加在URL的后面。你在瀏覽器的URL地址欄中會看到這些屬性,類似于
http://www.somesite/login.do?user=guest&password=guest&jsessionid=1001
從理論上來說,這3個部分(Request URL,Cookie Header, Message Body)都可以用來存放Session ID。由于Message Body方法必須需要一個包含Session ID的HTML Form,所以這種方法不通用。
一般用來實現Session的方法有兩種:
(1)URL重寫。
Web Server在返回Response的時候,檢查頁面中所有的URL,包括所有的連接,和HTML Form的Action屬性,在這些URL后面加上“;jsessionid=XXX”。
下一次,用戶訪問這個頁面中的URL。jsessionid就會傳回到Web Server。
(2)Cookie。
如果客戶端支持Cookie,Web Server在返回Response的時候,在Response的Header部分,加入一個“set-cookie: jsessionid=XXXX”header屬性,把jsessionid放在Cookie里傳到客戶端。
客戶端會把Cookie存放在本地文件里,下一次訪問Web Server的時候,再把Cookie的信息放到HTTP Request的“Cookie”header屬性里面,這樣jsessionid就隨著HTTP Request返回給Web Server。