posted @ 2011-11-04 17:31 云云 閱讀(2466) | 評論 (0) | 編輯 收藏
關(guān)于Hessian協(xié)議
http://www.3atesting.com/bbs/vie ... &extra=page%3D1
程序登陸和我們常用的http協(xié)議相似,都是通過網(wǎng)頁進(jìn)行操作!但是實(shí)際上他的應(yīng)用是采用Hessian協(xié)議進(jìn)行交互!所以看到腳本中很多都是二進(jìn)制代碼!那么什么是Hessian協(xié)議呢
目前,Web服務(wù)技術(shù)是解決異構(gòu)平臺系統(tǒng)的集成及互操作問題的主流技術(shù)[1]。它所基于的XML已經(jīng)是Internet上交換數(shù)據(jù)的實(shí)際標(biāo)準(zhǔn),基于通用的進(jìn)程間通信協(xié)議和網(wǎng)絡(luò)傳輸協(xié)議屏蔽平臺的差異,可以將各種異構(gòu)環(huán)境下的通信及調(diào)用請求均統(tǒng)一為標(biāo)準(zhǔn)的Web服務(wù)格式[3]。
但是由于SOAP協(xié)議的結(jié)構(gòu)問題會使封裝的數(shù)據(jù)膨脹數(shù)倍。當(dāng)傳輸數(shù)據(jù)量比較小時(shí),問題不是那么明顯,但是當(dāng)進(jìn)行大數(shù)據(jù)量傳輸時(shí)就會導(dǎo)致Web服務(wù)的傳輸性能在實(shí)際運(yùn)用中降低了很多。這對于經(jīng)常有大數(shù)據(jù)量數(shù)據(jù)交換的應(yīng)用系統(tǒng)來說是不適用的。
Caucho Technology公司制定的HBWSP(Hessian Binary Web Service Protocol)[2]在這方面的有所突破。Hessian協(xié)議和web service常用的SOAP協(xié)議類似,也是將協(xié)議報(bào)文封裝在HTTP封包中,通過HTTP信道進(jìn)行傳輸?shù)摹R虼薍essian協(xié)議具有與SOAP協(xié)議同樣的優(yōu)點(diǎn),即傳輸不受防火墻的限制(防火墻通常不限制HTTP信道)。Hessian協(xié)議的優(yōu)勢在于:它把本地格式的數(shù)據(jù)編碼為二進(jìn)制數(shù)據(jù),僅用一個(gè)字符作為結(jié)構(gòu)化標(biāo)記,HBWSP封裝后的數(shù)據(jù)增量明顯小于SOAP封裝后的數(shù)據(jù)增量。并且相對于SOAP,Hessian協(xié)議的外部數(shù)據(jù)表示有3個(gè)顯著的優(yōu)勢:
1)采用簡單的結(jié)構(gòu)化標(biāo)記。簡單的結(jié)構(gòu)化標(biāo)記減少了編碼、解碼操作對內(nèi)存的占用量。編碼時(shí),只需寫少量的數(shù)據(jù),就可以標(biāo)記結(jié)構(gòu);解碼時(shí),只需讀少量的數(shù)據(jù)就可以確定結(jié)構(gòu)。而且,簡單的結(jié)構(gòu)化標(biāo)記減少了編碼后的數(shù)據(jù)增量。
2)采用定長的字節(jié)記錄值。用定長的字節(jié)記錄值,解碼時(shí),就可以使用位操作從固定長度的位獲得值。這樣不僅操作簡單,而且可以獲得較高的性能。
3)采用引用取代重復(fù)遇到的對象。使用引用取代重復(fù)遇到的對象可以避免對重復(fù)對象的編碼,而且也減少了編碼后的數(shù)據(jù)量。
因此使用Hessian協(xié)議傳輸數(shù)據(jù)量比SOAP協(xié)議要小得多。實(shí)踐證明,傳輸同樣的對象Hessian協(xié)議傳輸?shù)臄?shù)據(jù)量比SOAP協(xié)議低一個(gè)數(shù)量級。因此Hessian協(xié)議比SOAP協(xié)議更適用于分布式應(yīng)用系統(tǒng)間大數(shù)據(jù)量的數(shù)據(jù)交換。
4.2 Hessian協(xié)議的實(shí)現(xiàn)構(gòu)架
Hessian協(xié)議的實(shí)現(xiàn)構(gòu)架如圖3所示:為了實(shí)現(xiàn)Hessian 構(gòu)架,設(shè)計(jì)了下列組件:編碼組件、解碼組件、通信組件、報(bào)告故障組件、代理組件、調(diào)用服務(wù)過程組件。

圖3 Hessian協(xié)議的實(shí)現(xiàn)構(gòu)架
首先客戶端發(fā)出本地請求,代理組件響應(yīng)請求依據(jù)服務(wù)接口,生成客戶端存根,并調(diào)用編碼組件對本地請求進(jìn)行基于Hessian Binary Web Service Protocol標(biāo)準(zhǔn)的二進(jìn)制編碼。然后調(diào)用通信組件將請求發(fā)送給服務(wù)器端。服務(wù)器端通信組件接收到請求后把請求轉(zhuǎn)發(fā)給調(diào)用服務(wù)過程組件,調(diào)用服務(wù)過程組件會首先調(diào)用解碼組件,得到過程標(biāo)識,將過程標(biāo)識轉(zhuǎn)給服務(wù)器端存根,并依據(jù)部署文件和客戶端的請求加載服務(wù)過程的實(shí)現(xiàn)類。然后根據(jù)過程標(biāo)識、過程參數(shù)調(diào)用服務(wù)過程。最后調(diào)用編碼組件將響應(yīng)結(jié)果進(jìn)行編碼并通過通信組件返回給客戶端。
當(dāng)數(shù)據(jù)傳輸、通信發(fā)生錯(cuò)誤的時(shí)候就需要啟用報(bào)告故障組件,它可以以異常的形式,報(bào)告發(fā)送端、接收端、或者網(wǎng)絡(luò)連接發(fā)生的故障,并把錯(cuò)誤記錄以日志的方式記錄下來保存在文件中,以備日后查閱。
4.3 實(shí)現(xiàn)結(jié)構(gòu)
針對教務(wù)管理系統(tǒng)互聯(lián)網(wǎng)傳輸存在的一系列問題,基于互聯(lián)網(wǎng)的主體數(shù)據(jù)平臺采用基于HBWSP的輕量級跨平臺通信技術(shù)實(shí)現(xiàn)數(shù)據(jù)交換,如圖4所示。在客戶端,應(yīng)用服務(wù)器從主題數(shù)據(jù)服務(wù)層中抽取數(shù)據(jù),并按著HBWSP的外部數(shù)據(jù)表示對本地格式數(shù)據(jù)進(jìn)行編碼。然后通過internet網(wǎng)進(jìn)行傳輸,在服務(wù)器端,數(shù)據(jù)交換的服務(wù)負(fù)責(zé)按照HBWSP的外部數(shù)據(jù)表示對接收到的數(shù)據(jù)進(jìn)行解碼,然后再對數(shù)據(jù)進(jìn)行分析、處理后把數(shù)據(jù)插入到服務(wù)器端的主題數(shù)據(jù)服務(wù)層中。

圖4非持久同步方式的數(shù)據(jù)交換解決方案
該解決方案的主要特點(diǎn)包括:
1)采用了HBWSP的二進(jìn)制編碼方式解決了異地、異構(gòu)平臺系統(tǒng)的通信問題,并使數(shù)據(jù)交互具有了一定的實(shí)時(shí)性。
2)由于HBWSP簡潔的編碼方式以及編碼、解碼性能高等特點(diǎn)使數(shù)據(jù)交換具有交換GB級數(shù)據(jù)的能力。
3)采用了HBWSP的二進(jìn)制編碼方式有助于縮短整個(gè)數(shù)據(jù)交換所需要的時(shí)間。其編碼性能高的特點(diǎn),有助于提高編碼速度,減少發(fā)送方編碼本地?cái)?shù)據(jù)的時(shí)間。其解碼性能高的特點(diǎn),可以減少接收方解碼、重構(gòu)本地?cái)?shù)據(jù)的時(shí)間。從而減少了數(shù)據(jù)交換的響應(yīng)時(shí)間。
4)采用了HBWSP的二進(jìn)制編碼方式和數(shù)據(jù)分批傳送技術(shù)有助于充分利用網(wǎng)絡(luò)狀況良好的時(shí)段??梢栽诰W(wǎng)絡(luò)狀況良好的時(shí)段盡可能多的完成數(shù)據(jù)交換。
5)采用了斷點(diǎn)續(xù)傳技術(shù),保證了當(dāng)網(wǎng)絡(luò)斷連或響應(yīng)超時(shí)導(dǎo)致正在進(jìn)行的數(shù)據(jù)交換被中斷,在故障修復(fù)后仍然可以從中斷處開始,繼續(xù)完成上次沒有完成的數(shù)據(jù)交換的能力。斷點(diǎn)的粒度可以調(diào)節(jié),可以是一條數(shù)據(jù),也可以是多條數(shù)據(jù)。
6)采用了事務(wù)保護(hù)機(jī)制,把每批要傳輸?shù)臄?shù)據(jù)定義為一個(gè)事務(wù),本批要傳輸?shù)臄?shù)據(jù)的事務(wù)完整性不依賴于已經(jīng)完成的各批數(shù)據(jù),本批數(shù)據(jù)傳輸發(fā)生錯(cuò)誤也不會對已經(jīng)完成的各批數(shù)據(jù)造成影響。采用這種方法,可以在數(shù)據(jù)交換過程被中斷的情況下保證數(shù)據(jù)交換事務(wù)的完整性。
posted @ 2011-11-04 16:57 云云 閱讀(4967) | 評論 (0) | 編輯 收藏





如果當(dāng)前元素已經(jīng)在map中了 就加1
第二種方法:









posted @ 2011-10-31 16:53 云云 閱讀(4658) | 評論 (0) | 編輯 收藏
一、cookie機(jī)制和session機(jī)制的區(qū)別
具體來說cookie機(jī)制采用的是在客戶端保持狀態(tài)的方案,而session機(jī)制采用的是在服務(wù)器端保持狀態(tài)的方案。
同時(shí)我們也看到,由于在服務(wù)器端保持狀態(tài)的方案在客戶端也需要保存一個(gè)標(biāo)識,所以session機(jī)制可能需要借助于cookie機(jī)制來達(dá)到保存標(biāo)識的目的,但實(shí)際上還有其他選擇。
二、會話cookie和持久cookie的區(qū)別
如果不設(shè)置過期時(shí)間,則表示這個(gè)cookie生命周期為瀏覽器會話期間,只要關(guān)閉瀏覽器窗口,cookie就消失了。這種生命期為瀏覽會話期的cookie被稱為會話cookie。會話cookie一般不保存在硬盤上而是保存在內(nèi)存里。
如果設(shè)置了過期時(shí)間,瀏覽器就會把cookie保存到硬盤上,關(guān)閉后再次打開瀏覽器,這些cookie依然有效直到超過設(shè)定的過期時(shí)間。
存儲在硬盤上的cookie可以在不同的瀏覽器進(jìn)程間共享,比如兩個(gè)IE窗口。而對于保存在內(nèi)存的cookie,不同的瀏覽器有不同的處理方式。
三、如何利用實(shí)現(xiàn)自動(dòng)登錄
當(dāng)用戶在某個(gè)網(wǎng)站注冊后,就會收到一個(gè)惟一用戶ID的cookie。客戶后來重新連接時(shí),這個(gè)用戶ID會自動(dòng)返回,服務(wù)器對它進(jìn)行檢查,確定它是否為注冊用戶且選擇了自動(dòng)登錄,從而使用戶無需給出明確的用戶名和密碼,就可以訪問服務(wù)器上的資源。
四、如何根據(jù)用戶的愛好定制站點(diǎn)
網(wǎng)站可以使用cookie記錄用戶的意愿。對于簡單的設(shè)置,網(wǎng)站可以直接將頁面的設(shè)置存儲在cookie中完成定制。然而對于更復(fù)雜的定制,網(wǎng)站只需僅將一個(gè)惟一的標(biāo)識符發(fā)送給用戶,由服務(wù)器端的數(shù)據(jù)庫存儲每個(gè)標(biāo)識符對應(yīng)的頁面設(shè)置。
五、cookie的發(fā)送
1.創(chuàng)建Cookie對象
2.設(shè)置最大時(shí)效
3.將Cookie放入到HTTP響應(yīng)報(bào)頭
如果你創(chuàng)建了一個(gè)cookie,并將他發(fā)送到瀏覽器,默認(rèn)情況下它是一個(gè)會話級別的cookie:存儲在瀏覽器的內(nèi)存中,用戶退出瀏覽器之后被刪除。如果你希望瀏覽器將該cookie存儲在磁盤上,則需要使用maxAge,并給出一個(gè)以秒為單位的時(shí)間。將最大時(shí)效設(shè)為0則是命令瀏覽器刪除該 cookie。
發(fā)送cookie需要使用HttpServletResponse的addCookie方法,將cookie插入到一個(gè) Set-Cookie HTTP請求報(bào)頭中。由于這個(gè)方法并不修改任何之前指定的Set-Cookie報(bào)頭,而是創(chuàng)建新的報(bào)頭,因此我們將這個(gè)方法稱為是addCookie,而非setCookie。同樣要記住響應(yīng)報(bào)頭必須在任何文檔內(nèi)容發(fā)送到客戶端之前設(shè)置。
六、cookie的讀取
1.調(diào)用request.getCookie
要獲取有瀏覽器發(fā)送來的cookie,需要調(diào)用HttpServletRequest的getCookies方法,這個(gè)調(diào)用返回Cookie對象的數(shù)組,對應(yīng)由HTTP請求中Cookie報(bào)頭輸入的值。
2.對數(shù)組進(jìn)行循環(huán),調(diào)用每個(gè)cookie的getName方法,直到找到感興趣的cookie為止
cookie與你的主機(jī)(域)相關(guān),而非你的servlet或JSP頁面。因而,盡管你的servlet可能只發(fā)送了單個(gè)cookie,你也可能會得到許多不相關(guān)的cookie。
例如:
String cookieName = “userID”;
Cookie cookies[] = request.getCookies();
if (cookies!=null){
for(int i=0;i<cookies.length;i++){
Cookie cookie = cookies[i];
if (cookieName.equals(cookie.getName())){
doSomethingWith(cookie.getValue());
}
}
}
七、如何使用cookie檢測初訪者
A.調(diào)用HttpServletRequest.getCookies()獲取Cookie數(shù)組
B.在循環(huán)中檢索指定名字的cookie是否存在以及對應(yīng)的值是否正確
C.如果是則退出循環(huán)并設(shè)置區(qū)別標(biāo)識
D.根據(jù)區(qū)別標(biāo)識判斷用戶是否為初訪者從而進(jìn)行不同的操作
八、使用cookie檢測初訪者的常見錯(cuò)誤
不能僅僅因?yàn)閏ookie數(shù)組中不存在在特定的數(shù)據(jù)項(xiàng)就認(rèn)為用戶是個(gè)初訪者。如果cookie數(shù)組為null,客戶可能是一個(gè)初訪者,也可能是由于用戶將cookie刪除或禁用造成的結(jié)果。
但是,如果數(shù)組非null,也不過是顯示客戶曾經(jīng)到過你的網(wǎng)站或域,并不能說明他們曾經(jīng)訪問過你的servlet。其它servlet、JSP頁面以及非Java Web應(yīng)用都可以設(shè)置cookie,依據(jù)路徑的設(shè)置,其中的任何cookie都有可能返回給用戶的瀏覽器。
正確的做法是判斷cookie數(shù)組是否為空且是否存在指定的Cookie對象且值正確。
九、使用cookie屬性的注意問題
屬性是從服務(wù)器發(fā)送到瀏覽器的報(bào)頭的一部分;但它們不屬于由瀏覽器返回給服務(wù)器的報(bào)頭。
因此除了名稱和值之外,cookie屬性只適用于從服務(wù)器輸出到客戶端的cookie;服務(wù)器端來自于瀏覽器的cookie并沒有設(shè)置這些屬性?!?br /> 因而不要期望通過request.getCookies得到的cookie中可以使用這個(gè)屬性。這意味著,你不能僅僅通過設(shè)置cookie的最大時(shí)效,發(fā)出它,在隨后的輸入數(shù)組中查找適當(dāng)?shù)腸ookie,讀取它的值,修改它并將它存回Cookie,從而實(shí)現(xiàn)不斷改變的cookie值。
十、如何使用cookie記錄各個(gè)用戶的訪問計(jì)數(shù)
1.獲取cookie數(shù)組中專門用于統(tǒng)計(jì)用戶訪問次數(shù)的cookie的值
2.將值轉(zhuǎn)換成int型
3.將值加1并用原來的名稱重新創(chuàng)建一個(gè)Cookie對象
4.重新設(shè)置最大時(shí)效
5.將新的cookie輸出
十一、session在不同環(huán)境下的不同含義
session,中文經(jīng)常翻譯為會話,其本來的含義是指有始有終的一系列動(dòng)作/消息,比如打電話是從拿起電話撥號到掛斷電話這中間的一系列過程可以稱之為一個(gè)session。
然而當(dāng)session一詞與網(wǎng)絡(luò)協(xié)議相關(guān)聯(lián)時(shí),它又往往隱含了“面向連接”和/或“保持狀態(tài)”這樣兩個(gè)含義。
session在Web開發(fā)環(huán)境下的語義又有了新的擴(kuò)展,它的含義是指一類用來在客戶端與服務(wù)器端之間保持狀態(tài)的解決方案。有時(shí)候Session也用來指這種解決方案的存儲結(jié)構(gòu)。
十二、session的機(jī)制
session機(jī)制是一種服務(wù)器端的機(jī)制,服務(wù)器使用一種類似于散列表的結(jié)構(gòu)(也可能就是使用散列表)來保存信息。
但程序需要為某個(gè)客戶端的請求創(chuàng)建一個(gè)session的時(shí)候,服務(wù)器首先檢查這個(gè)客戶端的請求里是否包含了一個(gè)session標(biāo)識-稱為session id,如果已經(jīng)包含一個(gè)session id則說明以前已經(jīng)為此客戶創(chuàng)建過session,服務(wù)器就按照session id把這個(gè)session檢索出來使用(如果檢索不到,可能會新建一個(gè),這種情況可能出現(xiàn)在服務(wù)端已經(jīng)刪除了該用戶對應(yīng)的session對象,但用戶人為地在請求的URL后面附加上一個(gè)JSESSION的參數(shù))。
如果客戶請求不包含session id,則為此客戶創(chuàng)建一個(gè)session并且生成一個(gè)與此session相關(guān)聯(lián)的session id,這個(gè)session id將在本次響應(yīng)中返回給客戶端保存。
十三、保存session id的幾種方式
A.保存session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動(dòng)的按照規(guī)則把這個(gè)標(biāo)識發(fā)送給服務(wù)器。
B.由于cookie可以被人為的禁止,必須有其它的機(jī)制以便在cookie被禁止時(shí)仍然能夠把session id傳遞回服務(wù)器,經(jīng)常采用的一種技術(shù)叫做URL重寫,就是把session id附加在URL路徑的后面,附加的方式也有兩種,一種是作為URL路徑的附加信息,另一種是作為查詢字符串附加在URL后面。網(wǎng)絡(luò)在整個(gè)交互過程中始終保持狀態(tài),就必須在每個(gè)客戶端可能請求的路徑后面都包含這個(gè)session id。
C.另一種技術(shù)叫做表單隱藏字段。就是服務(wù)器會自動(dòng)修改表單,添加一個(gè)隱藏字段,以便在表單提交時(shí)能夠把session id傳遞回服務(wù)器。
十四、session什么時(shí)候被創(chuàng)建
一個(gè)常見的錯(cuò)誤是以為session在有客戶端訪問時(shí)就被創(chuàng)建,然而事實(shí)是直到某server端程序(如Servlet)調(diào)用HttpServletRequest.getSession(true)這樣的語句時(shí)才會被創(chuàng)建。
十五、session何時(shí)被刪除
session在下列情況下被刪除:
A.程序調(diào)用HttpSession.invalidate()
B.距離上一次收到客戶端發(fā)送的session id時(shí)間間隔超過了session的最大有效時(shí)間
C.服務(wù)器進(jìn)程被停止
再次注意關(guān)閉瀏覽器只會使存儲在客戶端瀏覽器內(nèi)存中的session cookie失效,不會使服務(wù)器端的session對象失效。
十六、URL重寫有什么缺點(diǎn)
對所有的URL使用URL重寫,包括超鏈接,form的action,和重定向的URL。每個(gè)引用你的站點(diǎn)的URL,以及那些返回給用戶的URL(即使通過間接手段,比如服務(wù)器重定向中的Location字段)都要添加額外的信息。
這意味著在你的站點(diǎn)上不能有任何靜態(tài)的HTML頁面(至少靜態(tài)頁面中不能有任何鏈接到站點(diǎn)動(dòng)態(tài)頁面的鏈接)。因此,每個(gè)頁面都必須使用servlet或 JSP動(dòng)態(tài)生成。即使所有的頁面都動(dòng)態(tài)生成,如果用戶離開了會話并通過書簽或鏈接再次回來,會話的信息都會丟失,因?yàn)榇鎯ο聛淼逆溄雍绣e(cuò)誤的標(biāo)識信息-該URL后面的SESSION ID已經(jīng)過期了?! ?/p>
十七、使用隱藏的表單域有什么缺點(diǎn)
僅當(dāng)每個(gè)頁面都是有表單提交而動(dòng)態(tài)生成時(shí),才能使用這種方法。單擊常規(guī)的<A HREF..>超文本鏈接并不產(chǎn)生表單提交,因此隱藏的表單域不能支持通常的會話跟蹤,只能用于一系列特定的操作中,比如在線商店的結(jié)賬過程。
十八、會話跟蹤的基本步驟
1.訪問與當(dāng)前請求相關(guān)的會話對象
2.查找與會話相關(guān)的信息
3.存儲會話信息
4.廢棄會話數(shù)據(jù)
十九、getSession()/getSession(true)、getSession(false)的區(qū)別
getSession()/getSession(true):當(dāng)session存在時(shí)返回該session,否則新建一個(gè)session并返回該對象
getSession(false):當(dāng)session存在時(shí)返回該session,否則不會新建session,返回null
二十、如何將信息與會話關(guān)聯(lián)起來
setAttribute會替換任何之前設(shè)定的值;如果想要在不提供任何代替的情況下移除某個(gè)值,則應(yīng)使用removeAttribute。這個(gè)方法會觸發(fā)所有實(shí)現(xiàn)了HttpSessionBindingListener接口的值的valueUnbound方法。
二十一、會話屬性的類型有什么限制嗎
通常會話屬性的類型只要是Object就可以了。除了null或基本類型,如int,double,boolean。
如果要使用基本類型的值作為屬性,必須將其轉(zhuǎn)換為相應(yīng)的封裝類對象
二十二、如何廢棄會話數(shù)據(jù)
A.只移除自己編寫的servlet創(chuàng)建的數(shù)據(jù):
調(diào)用removeAttribute(“key”)將指定鍵關(guān)聯(lián)的值廢棄
B.刪除整個(gè)會話(在當(dāng)前Web應(yīng)用中):
調(diào)用invalidate,將整個(gè)會話廢棄掉。這樣做會丟失該用戶的所有會話數(shù)據(jù),而非僅僅由我們servlet或JSP頁面創(chuàng)建的會話數(shù)據(jù)
C.將用戶從系統(tǒng)中注銷并刪除所有屬于他(或她)的會話
調(diào)用logOut,將客戶從Web服務(wù)器中注銷,同時(shí)廢棄所有與該用戶相關(guān)聯(lián)的會話(每個(gè)Web應(yīng)用至多一個(gè))。這個(gè)操作有可能影響到服務(wù)器上多個(gè)不同的Web應(yīng)用。
二十三、使用isNew來判斷用戶是否為新舊用戶的錯(cuò)誤做法
public boolean isNew()方法如果會話尚未和客戶程序(瀏覽器)發(fā)生任何聯(lián)系,則這個(gè)方法返回true,這一般是因?yàn)闀捠切陆ǖ模皇怯奢斎氲目蛻粽埱笏鸬摹?br /> 但如果isNew返回false,只不過是說明他之前曾經(jīng)訪問該Web應(yīng)用,并不代表他們曾訪問過我們的servlet或JSP頁面。
因?yàn)閟ession是與用戶相關(guān)的,在用戶之前訪問的每一個(gè)頁面都有可能創(chuàng)建了會話。因此isNew為false只能說用戶之前訪問過該Web應(yīng)用,session可以是當(dāng)前頁面創(chuàng)建,也可能是由用戶之前訪問過的頁面創(chuàng)建的。
正確的做法是判斷某個(gè)session中是否存在某個(gè)特定的key且其value是否正確
二十四、Cookie的過期和Session的超時(shí)有什么區(qū)別
會話的超時(shí)由服務(wù)器來維護(hù),它不同于Cookie的失效日期。首先,會話一般基于駐留內(nèi)存的cookie不是持續(xù)性的cookie,因而也就沒有截至日期。即使截取到JSESSIONID cookie,并為它設(shè)定一個(gè)失效日期發(fā)送出去。瀏覽器會話和服務(wù)器會話也會截然不同。
二十五、session cookie和session對象的生命周期是一樣的嗎
當(dāng)用戶關(guān)閉了瀏覽器雖然session cookie已經(jīng)消失,但session對象仍然保存在服務(wù)器端
二十六、是否只要關(guān)閉瀏覽器,session就消失了
程序一般都是在用戶做log off的時(shí)候發(fā)個(gè)指令去刪除session,然而瀏覽器從來不會主動(dòng)在關(guān)閉之前通知服務(wù)器它將要被關(guān)閉,因此服務(wù)器根本不會有機(jī)會知道瀏覽器已經(jīng)關(guān)閉。服務(wù)器會一直保留這個(gè)會話對象直到它處于非活動(dòng)狀態(tài)超過設(shè)定的間隔為止。
之所以會有這種錯(cuò)誤的認(rèn)識,是因?yàn)榇蟛糠謘ession機(jī)制都使用會話cookie來保存session id,而關(guān)閉瀏覽器后這個(gè)session id就消失了,再次連接到服務(wù)器時(shí)也就無法找到原來的session。
如果服務(wù)器設(shè)置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發(fā)出的HTTP請求報(bào)頭,把原來的session id發(fā)送到服務(wù)器,則再次打開瀏覽器仍然能夠找到原來的session。
恰恰是由于關(guān)閉瀏覽器不會導(dǎo)致session被刪除,迫使服務(wù)器為session設(shè)置了一個(gè)失效時(shí)間,當(dāng)距離客戶上一次使用session的時(shí)間超過了這個(gè)失效時(shí)間時(shí),服務(wù)器就可以認(rèn)為客戶端已經(jīng)停止了活動(dòng),才會把session刪除以節(jié)省存儲空間。
由此我們可以得出如下結(jié)論:
關(guān)閉瀏覽器,只會是瀏覽器端內(nèi)存里的session cookie消失,但不會使保存在服務(wù)器端的session對象消失,同樣也不會使已經(jīng)保存到硬盤上的持久化cookie消失。
二十七、打開兩個(gè)瀏覽器窗口訪問應(yīng)用程序會使用同一個(gè)session還是不同的session
通常session cookie是不能跨窗口使用的,當(dāng)你新開了一個(gè)瀏覽器窗口進(jìn)入相同頁面時(shí),系統(tǒng)會賦予你一個(gè)新的session id,這樣我們信息共享的目的就達(dá)不到了。
此時(shí)我們可以先把session id保存在persistent cookie中(通過設(shè)置session的最大有效時(shí)間),然后在新窗口中讀出來,就可以得到上一個(gè)窗口的session id了,這樣通過session cookie和persistent cookie的結(jié)合我們就可以實(shí)現(xiàn)了跨窗口的會話跟蹤。
二十八、如何使用會話顯示每個(gè)客戶的訪問次數(shù)
由于客戶的訪問次數(shù)是一個(gè)整型的變量,但session的屬性類型中不能使用int,double,boolean等基本類型的變量,所以我們要用到這些基本類型的封裝類型對象作為session對象中屬性的值
但像Integer是一種不可修改(Immutable)的數(shù)據(jù)結(jié)構(gòu):構(gòu)建后就不能更改。這意味著每個(gè)請求都必須創(chuàng)建新的Integer對象,之后使用setAttribute來代替之前存在的老的屬性的值。例如:
HttpSession session = request.getSession();
SomeImmutalbeClass value = (SomeImmutableClass)session.getAttribute(“SomeIdentifier”);
if (value= =null){
value = new SomeImmutableClass(…); // 新創(chuàng)建一個(gè)不可更改對象
}else{
value = new SomeImmutableClass(calculatedFrom(value)); // 對value重新計(jì)算后創(chuàng)建新的對象
}
session.setAttribute(“someIdentifier”,value); // 使用新創(chuàng)建的對象覆蓋原來的老的對象
二十九、如何使用會話累計(jì)用戶的數(shù)據(jù)
使用可變的數(shù)據(jù)結(jié)構(gòu),比如數(shù)組、List、Map或含有可寫字段的應(yīng)用程序?qū)S械臄?shù)據(jù)結(jié)構(gòu)。通過這種方式,除非首次分配對象,否則不需要調(diào)用setAttribute。例如
HttpSession session = request.getSession();
SomeMutableClass value = (SomeMutableClass)session.getAttribute(“someIdentifier”);
if(value = = null){
value = new SomeMutableClass(…);
session.setAttribute(“someIdentifier”,value);
}else{
value.updateInternalAttribute(…); // 如果已經(jīng)存在該對象則更新其屬性而不需重新設(shè)置屬性
}
三十、不可更改對象和可更改對象在會話數(shù)據(jù)更新時(shí)的不同處理
不可更改對象因?yàn)橐坏﹦?chuàng)建之后就不能更改,所以每次要修改會話中屬性的值的時(shí)候,都需要調(diào)用 setAttribute(“someIdentifier”,newValue)來代替原有的屬性的值,否則屬性的值不會被更新可更改對象因?yàn)槠渥陨硪话闾峁┝诵薷淖陨韺傩缘姆椒?,所以每次要修改會話中屬性的值的時(shí)候,只要調(diào)用該可更改對象的相關(guān)修改自身屬性的方法就可以了。這意味著我們就不需要調(diào)用 setAttribute方法了。
posted @ 2011-10-29 14:34 云云 閱讀(298) | 評論 (0) | 編輯 收藏
最后google一下 發(fā)現(xiàn)有人提供了方法 大謝
找到你的android-sdk-windows\platform-tools目錄,打開后會發(fā)現(xiàn)里面有許多文件。
找到adb.exe,AdbWinApi.dll,AdbWinUsbApi.dll這三個(gè)文件,將這三個(gè)文件拷到你android-sdk-windows\tools目錄下。
試用成功
posted @ 2011-10-16 17:53 云云 閱讀(2027) | 評論 (0) | 編輯 收藏
1 對著工程點(diǎn)擊鼠標(biāo)右鍵 選擇 Build Project,R.java 文件又回來。這樣R.xx.xxx 就能 X 的出來了。
如果不行 試用第二種 方法
2 選擇eclipse/myeclipse 的 clean 這樣R文件也會出現(xiàn)
如果還不行 試用第三種
3 經(jīng)過上面兩種方法都不行 使用絕招 從別的工程中拷貝一份R文件過來 然后string.xml里隨便改動(dòng)一下 即可更新R文件
如果還不行 試用第四種
4 經(jīng)過上面的3種方法都不行 說明我們的工程有問題 好好檢查吧
比如resoure資源中的文件 命名,例result_main.xml,如果寫成Result_main.xml是錯(cuò)誤的 需要全部小寫
posted @ 2011-10-13 23:56 云云 閱讀(76970) | 評論 (6) | 編輯 收藏
但是用同樣的方法在myeclipse上裝adt的插件時(shí) 就不好用 在網(wǎng)上找了很久
找到了這份記錄 就摘過來了 一起分享 呵呵
原文:http://blog.csdn.net/paulluo0739/article/details/6656516
使用MyEclipse8.5的自動(dòng)加載組件功能,會把原本的J2EE插件給干掉,實(shí)在是可氣,造成adt加上了,但J2EE不能用的尷尬狀況。卸載之后使用手動(dòng)添加adt插件的方法可避免該問題。
1、下載最新的adt插件ADT-10.0.1.zip
2、zip解壓出plugins下的四個(gè)jar包:
com.android.ide.eclipse.adt_10.0.1.v201103111512-110841.jar
com.android.ide.eclipse.ddms_10.0.1.v201103111512-110841.jar
com.android.ide.eclipse.hierarchyviewer_10.0.1.v201103111512-110841.jar
com.android.ide.eclipse.traceview_10.0.1.v201103111512-110841.jar
3、復(fù)制到MyEclipse8.5的\Common\plugins目錄下
4、修改MyEclipse 8.5\configuration\org.eclipse.equinox.simpleconfigurator目錄下的bundles.info文件,添加以下內(nèi)容:
com.android.ide.eclipse.adt,10.0.1.v201103111512-110841,file:/D:/Program Files/MyEclipse 8.5/Common/plugins/com.android.ide.eclipse.adt_10.0.1.v201103111512-110841.jar,4,false
com.android.ide.eclipse.ddms,10.0.1.v201103111512-110841,file:/D:/Program Files/MyEclipse 8.5/Common/plugins/com.android.ide.eclipse.ddms_10.0.1.v201103111512-110841.jar,4,false
com.android.ide.eclipse.hierarchyviewer,10.0.1.v201103111512-110841,file:/D:/Program Files/MyEclipse 8.5/Common/plugins/com.android.ide.eclipse.hierarchyviewer_10.0.1.v201103111512-110841.jar,4,false
com.android.ide.eclipse.traceview,10.0.1.v201103111512-110841,file:/D:/Program Files/MyEclipse 8.5/Common/plugins/com.android.ide.eclipse.traceview_10.0.1.v201103111512-110841.jar,4,false
5、重啟MyEclipse
posted @ 2011-10-10 10:31 云云 閱讀(7080) | 評論 (0) | 編輯 收藏
個(gè)人的安裝方法如下:
1.首先下載SVN包:site -1.6.17 http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240
2.解壓SVN包,然后找到其中的兩個(gè)文件夾:features 和 plugins
3.隨意建一個(gè)文件夾(位置和名稱自己定就好了,我的是E:\myEclipsePlugin\svn),然后把第二步的解壓好的features 和 plugins放到這個(gè)文件夾下
4.找到myeclipse的安裝目錄,下面有一個(gè)configuration\org.eclipse.equinox.simpleconfigurator\bundles.info 文件?,F(xiàn)在需要做的就是在該文件內(nèi)添加的東西
5.添加的內(nèi)容用下面的類生成:

如果把svn文件放在了這個(gè)位置 就不用動(dòng)行上面的java代碼了 因?yàn)槲乙呀?jīng)運(yùn)行過一次了 下面把生成的東東貼出來 就可以直接用了com.collabnet.subversion.merge.feature,2.2.4,file:/D:/Program Files/Genuitec/site-1.6.18/features/com.collabnet.subversion.merge.feature_2.2.4.jar,4,false
com.sun.jna,3.2.7,file:/D:/Program Files/Genuitec/site-1.6.18/features/com.sun.jna_3.2.7.jar,4,false
org.tigris.subversion.clientadapter.feature,1.6.12,file:/D:/Program Files/Genuitec/site-1.6.18/features/org.tigris.subversion.clientadapter.feature_1.6.12.jar,4,false
org.tigris.subversion.clientadapter.javahl.feature,1.6.17,file:/D:/Program Files/Genuitec/site-1.6.18/features/org.tigris.subversion.clientadapter.javahl.feature_1.6.17.jar,4,false
org.tigris.subversion.clientadapter.svnkit.feature,1.6.15,file:/D:/Program Files/Genuitec/site-1.6.18/features/org.tigris.subversion.clientadapter.svnkit.feature_1.6.15.jar,4,false
org.tigris.subversion.subclipse.graph.feature,1.0.9,file:/D:/Program Files/Genuitec/site-1.6.18/features/org.tigris.subversion.subclipse.graph.feature_1.0.9.jar,4,false
org.tigris.subversion.subclipse.mylyn,3.0.0,file:/D:/Program Files/Genuitec/site-1.6.18/features/org.tigris.subversion.subclipse.mylyn_3.0.0.jar,4,false
org.tigris.subversion.subclipse,1.6.18,file:/D:/Program Files/Genuitec/site-1.6.18/features/org.tigris.subversion.subclipse_1.6.18.jar,4,false
org.tmatesoft.svnkit,1.3.5.7406,file:/D:/Program Files/Genuitec/site-1.6.18/features/org.tmatesoft.svnkit_1.3.5.7406.jar,4,false
com.collabnet.subversion.merge,2.2.4,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/com.collabnet.subversion.merge_2.2.4.jar,4,false
com.sun.jna,3.2.7,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/com.sun.jna_3.2.7.jar,4,false
org.tigris.subversion.clientadapter.javahl.win32,1.6.17,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/org.tigris.subversion.clientadapter.javahl.win32_1.6.17.jar,4,false
org.tigris.subversion.clientadapter.javahl,1.6.17,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/org.tigris.subversion.clientadapter.javahl_1.6.17.jar,4,false
org.tigris.subversion.clientadapter.svnkit,1.6.15,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/org.tigris.subversion.clientadapter.svnkit_1.6.15.jar,4,false
org.tigris.subversion.clientadapter,1.6.12,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/org.tigris.subversion.clientadapter_1.6.12.jar,4,false
org.tigris.subversion.subclipse.core,1.6.18,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/org.tigris.subversion.subclipse.core_1.6.18.jar,4,false
org.tigris.subversion.subclipse.doc,1.3.0,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/org.tigris.subversion.subclipse.doc_1.3.0.jar,4,false
org.tigris.subversion.subclipse.graph,1.0.9,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/org.tigris.subversion.subclipse.graph_1.0.9.jar,4,false
org.tigris.subversion.subclipse.mylyn,3.0.0,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/org.tigris.subversion.subclipse.mylyn_3.0.0.jar,4,false
org.tigris.subversion.subclipse.tools.usage,1.0.1,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/org.tigris.subversion.subclipse.tools.usage_1.0.1.jar,4,false
org.tigris.subversion.subclipse.ui,1.6.18,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/org.tigris.subversion.subclipse.ui_1.6.18.jar,4,false
org.tmatesoft.svnkit,1.3.5.7406,file:/D:/Program Files/Genuitec/site-1.6.18/plugins/org.tmatesoft.svnkit_1.3.5.7406.jar,4,false
6.把以上生成的字符串(一大堆)添加到第四步bundles.info文件的后面,然后重啟myeclipse即可。
posted @ 2011-10-09 17:38 云云 閱讀(4392) | 評論 (1) | 編輯 收藏
由于項(xiàng)目中使用的log4j.xml這種配置 在網(wǎng)上找到這份介紹較全的 就摘錄下來 一起分享
使用log4j
獲取logger
Logger.getRootLogger() 獲取根logger
Logger.getLogger(String name)獲取子logger
Logger.getLogger(Class clazz)或
Logger.getLogger(clazz.getName())
設(shè)置日志級別(.setLevel(int,Exception))
Level.ALL打開所有日志
Level.DEBUG 用于調(diào)試
Level.INFO 用于運(yùn)行過程
Level.WARN 用于潛在的錯(cuò)誤
Level.ERROR 用于錯(cuò)誤事件
Level.FATAL 用于嚴(yán)重錯(cuò)誤時(shí)間
Level.OFF 關(guān)閉所有日志
輸出端Appender(.addAppender(Appender).setAdditivity(boolean additive)是否覆蓋)
org.apache.log4j.ConsoleAppender 輸出到控制臺
targer:
ConsoleAppender.SYSTEM_OUT(Default)
ConsoleAppender.SYSTEM_ERR
public ConsoleAppender(Layout)
public ConsoleAppender(Layout,String targer)
org.apache.log4j.FileAppender 輸出到文件
public FileAppender(Layout,String fileName)
public FileAppender(Layout,String fileName,boolean append)是否覆蓋
org.apache.log4j.DailyRollingFileAppender 輸出到文件,每天一個(gè)新文件
org.apache.log4j.RollingFileAppender 輸出到文件,自動(dòng)新增改名
public RollingFileAppender(Layout,String fileName)
void setMaxBackupIndex(int index) 設(shè)置日志文件最大備份數(shù)
void setMaximumFileSize(long size) 設(shè)置日志文件最大尺寸
org.apache.log4j.WriterAppender 流格式輸出到任意地方
org.apache.log4j.JDBCAppender 輸出到數(shù)據(jù)庫
日志格式化(Layout)
%c 類全名
%d 時(shí)間
%f 類名
%l 位置
%m 信息
%n 換行
%p 級別
%r 耗時(shí)
%t 線程名
public PatternLayout() 使用默認(rèn)設(shè)置DEFAULT_CONVERSION_PATTERN 只打印信息
public PatternLayout(String)使用自定義的pattern構(gòu)造一個(gè)PatternLayout
void setConversionPattern(String) 設(shè)置日志格式
HTMLLayout
SimpleLayout
5.
1.BasicConfigurator.configure()
PatternLayout p = new PatternLayout("%p [%t] %c (%F:%L) - %m%n");
ConsoleAppender a = new ConsoleAppender(p,ConsoleAppender.SYSTEM_OUT);
root.addAppender(a);
rootLogger.setLevel(Level.DEBUG);
2.PropertyConfigurator.configure("/help/example.properties")
String resource = "/help/example.properties";
URL configFileResource = Log4J.class.getResource(resource);
PropertyConfigurator.configure(configFileResource);
3.DOMConfigurator.configure("/help/example.xml")
xml declaration and dtd
|
log4j:configuration
|
+-- appender (name, class)
| |
| +-- param (name, value)
| +-- layout (class)
| |
| +-- param (name, value)
+-- logger (name, additivity)
| |
| +-- level (class, value)
| | |
| | +-- param (name, value)
| +-- appender-ref (ref)
+-- root
|
+-- param (name, class)
+-- level
| |
| +-- param (name, value)
+-- appender-ref (ref)
0.log4j.properties模板
log4j.rootLogger=info,CONSOLE,RFILE,FILE,DB 設(shè)置級別和三個(gè)輸出端
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Target=System.out 控制臺類型
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern= %4p [%t] (%F:%L) - %m%n
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=/help/my.properties 目標(biāo)文件
log4j.appender.FILE.Append=false 是否追加
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout 布局模式
log4j.appender.FILE.layout.ConversionPattern=%d{yyyy-MM-dd hh:mm:ss}:%p %c:%L - %m%n 格式化布局
log4j.appender.RFILE=org.apache.log4j.RollingFileAppender
log4j.appender.RFILE.File=/help/my.properties 目標(biāo)文件
log4j.appender.RFILE.MaxFileSize=1KB 最大長度
log4j.appender.RFILE.MaxBackupIndex=3 最多備份
log4j.appender.RFILE.layout=org.apache.log4j.PatternLayout 布局模式
log4j.appender.RFILE.layout.ConversionPattern=%d{yyyy-MM-dd hh:mm:ss}:%p %c:%L - %m%n 格式化布局
log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DB.URL=jdbc:oracle:thin:@127.0.0.1:1521:mumu URL
log4j.appender.DB.driver=oracle.jdbc.driver.OracleDriver 驅(qū)動(dòng)
log4j.appender.DB.user=liulibo 用戶名
log4j.appender.DB.password=liulibo 密碼
log4j.appender.DB.layout=org.apache.log4j.PatternLayout 布局模式
log4j.appender.DB.layout.ConversionPattern=insert into log4j(createdate,thread,level_,class,message) values(\'%d\',\'%t\',\'%-5p\',\'%c\',\'%m\')
create table log4j(createdate varchar2(32),thread varchar2(32),level_ varchar2(32),class varchar2(32),message varchar2(32));
0.XML模板
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd hh:mm:ss}:%p %t %c - %m%n"/>
</layout>
</appender>
<appender name="RollingFileAppender" class="org.apache.log4j.RollingFileAppender">
<param name="Append" value="false"/>
<param name="MaxFileSize" value="1KB"/>
<param name="File" value="dom/my.log"/>
<param name="MaxBackupIndex" value="3"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd hh:mm:ss}:%p %t %c - %m%n"/>
</layout>
</appender>
<appender name="JDBCAppender" class="org.apache.log4j.jdbc.JDBCAppender">
<param name="URL" value="jdbc:oracle:thin:@127.0.0.1:1521:mumu"/>
<param name="user" value="liulibo"/>
<param name="password" value="liulibo"/>
<param name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="insert into log4j(createdate,thread,level_,class,message) values(\'%d\',\'%t\',\'%-5p\',\'%c\',\'%m\')"/>
</layout>
</appender>
<root>
<priority value ="debug" />
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="RollingFileAppender"/>
<appender-ref ref="JDBCAppender"/>
</root>
</log4j:configuration>
應(yīng)用
web.xml
<context-param>
<param-name>props</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<listener>
<listener-class>cart.listener.SCServletContextListener</listener-class>
</listener>
初始化方法中添加
private void initLog4j(ServletContext context){
String prefix = context.getRealPath("/");
System.out.println("prefix:"+prefix);
String props = context.getInitParameter("props");
if(props != null) {
PropertyConfigurator.configure(prefix+props);
}
Logger logger = Logger.getLogger(SCServletContextListener.class);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration threshold="debug"
xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="console.CONSOLE"
class="org.apache.log4j.ConsoleAppender">
<param name="threshold" value="debug" />
<layout class="org.apache.log4j.PatternLayout">
<!--
<param name="ConversionPattern" value="%d{HH:mm:ss}[%C.%M(%L)-%p] %m%n"/>
-->
<param name="ConversionPattern" value="%d{HH:mm:ss}[%C(%L)-%p] %m%n"/>
</layout>
</appender>
<appender name="file.text.SYSFILE"
class="org.apache.log4j.RollingFileAppender">
<param name="threshold" value="error" />
<param name="file" value="/juyee.log" />
<param name="maxFileSize" value="2MB" />
<param name="maxBackupIndex" value="5" />
<param name="append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-d{yyyy-MM-dd HH:mm:ss.SSS} [%p]-[%c] %m%n" />
</layout>
</appender>
<appender name="file.text.DATE_FILE"
class="org.apache.log4j.DailyRollingFileAppender">
<param name="threshold" value="debug" />
<param name="file" value="/juyee.log" />
<param name="append" value="true" />
<param name="datePattern" value="'.'yyyy-MM-dd" />
<!-- each hour
<param name="DatePattern" value="'.'yyyy-MM-dd-HH"/>
-->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] %m%n" />
</layout>
</appender>
<appender name="file.text.APPFILE"
class="org.apache.log4j.RollingFileAppender">
<param name="threshold" value="error" />
<param name="file" value="${webapp.root}/WEB-INF/logs/juyee.log" />
<param name="maxFileSize" value="1024KB" />
<param name="maxBackupIndex" value="5" />
<param name="append" value="true" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%d %-5p %c - %m [%t] (%F:%L)%n" />
</layout>
</appender>
<appender name="file.html.HTML"
class="org.apache.log4j.RollingFileAppender">
<param name="threshold" value="error" />
<param name="file" value="/juyee-log.html" />
<param name="maxFileSize" value="1024KB" />
<param name="maxBackupIndex" value="5" />
<param name="append" value="true" />
<layout class="org.apache.log4j.HTMLLayout" />
</appender>
<appender name="file.xml.XML"
class="org.apache.log4j.RollingFileAppender">
<param name="threshold" value="error" />
<param name="file" value="/juyee-log.xml" />
<param name="maxFileSize" value="1024KB" />
<param name="maxBackupIndex" value="5" />
<param name="append" value="true" />
<layout class="org.apache.log4j.xml.XMLLayout" />
</appender>
<appender name="mail.MAIL" class="org.apache.log4j.net.SMTPAppender">
<param name="threshold" value="debug"/>
<!--
<param name="threshold" value="fatal"/>
-->
<param name="BufferSize" value="10"/>
<param name="From" value="yangguanjun@justonetech.com"/>
<param name="SMTPHost" value="www.justonetech.com"/>
<param name="Subject" value="juyee-log4jMessage"/>
<param name="To" value="yangguanjun@justonetech.com"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss.SSS} [%p]-[%c] %m%n" />
</layout>
</appender>
<appender name="remote.CHAINSAW"
class="org.apache.log4j.net.SocketAppender">
<param name="threshold" value="fatal" />
<param name="remoteHost" value="localhost" />
<param name="port" value="4445" />
<param name="locationInfo" value="true" />
</appender>
<category name="com.juyee" additivity="true">
<priority value="info" />
<appender-ref ref="console.CONSOLE" />
<!--
<appender-ref ref="file.text.DATE_FILE" />
-->
</category>
<category name="com.co" additivity="true">
<priority value="debug" />
<appender-ref ref="console.CONSOLE" />
<appender-ref ref="file.text.DATE_FILE" />
</category>
<category name="org" additivity="true">
<priority value="WARN" />
<appender-ref ref="console.CONSOLE" />
<!--
<appender-ref ref="file.text.DATE_FILE" />
-->
</category>
<root>
<!--
<level value="trace" />
<level value="debug" />
<level value="info" />
<level value="warn" />
<level value="error" />
<level value="fatal" />
<appender-ref ref="console.CONSOLE" />
<appender-ref ref="file.text.DATE_FILE"/>
-->
</root>
</log4j:configuration>
===================================================
今天弄mondrian時(shí)才注意log4j.xml,原來一直使用log4j.properties,發(fā)現(xiàn)它比properties功能強(qiáng)大,可以配置輸出多個(gè)log文件。
轉(zhuǎn)一個(gè)基本的配置:
log4j 有兩種配置方法,大家熟知的是properties文件但是最近的項(xiàng)目實(shí)施中,每次去用戶那里裝系統(tǒng),都要苦惱于log文件放在不同位置,要改property文件就要重打jar包,麻煩的緊。而如果采用xml配置的方法,直接放在WEB-INFO下,要修改路徑,很方便。查了些資料,終于把系統(tǒng)的log4j改成在xml中配置啦。
記一下記一下……嘿嘿
附:log4j的API http://logging.apache.org/log4j/docs/api/index.html
log4i.xml 文件
<?xml version="1.0" encoding="GB2312" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="FILE"
class="org.apache.log4j.RollingFileAppender">
<!-- 設(shè)置通道file和輸出方式:org.apache.log4j.RollingFileAppender -->
<param name="File" value="D:/zhaotj/all.output.log" /><!-- 設(shè)置File參數(shù):日志輸出文件名 -->
<param name="Append" value="true" /><!-- 設(shè)置是否在重新啟動(dòng)服務(wù)時(shí),在原有日志的基礎(chǔ)添加新日志 -->
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%p (%c:%L)- %m%n" /><!-- 設(shè)置輸出文件項(xiàng)目和格式 -->
</layout>
</appender>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<!-- 設(shè)置監(jiān)視器輸出方式 -->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern"
value="%-4r [%t] %-5p %c %x - %m%n" />
</layout>
<!--濾鏡設(shè)置輸出的級別-->
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="levelMin" value="info" />
<param name="levelMax" value="info" />
<param name="AcceptOnMatch" value="true" />
</filter>
</appender>
<root><!-- 設(shè)置接收所有輸出的通道 -->
<priority value="info" />
<appender-ref ref="FILE" /><!-- 與前面的通道id相對應(yīng) -->
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
建好xml文件后 要寫一個(gè)servlet類繼承actionservlet,當(dāng)工程初始化時(shí)自動(dòng)加載xml配置文件
package com.asiainfo;
import javax.servlet.ServletException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.xml.DOMConfigurator;
import org.apache.struts.action.ActionServlet;
public class ExtendedActionServlet extends ActionServlet {
private Log log = LogFactory.getLog(this.getClass().getName());
public ExtendedActionServlet() {}
public void init() throws ServletException {
log.info(
"Initializing, My MyActionServlet init this System's Const Variable");
String prefix = this.getServletConfig().getServletContext().getRealPath(
"/");//讀取項(xiàng)目的路徑
String file = this.getServletConfig().getInitParameter("log4j");
//讀取log4j相對路徑
String filePath = prefix + file;
DOMConfigurator.configure(filePath);//加載.xml文件
log.info("Initializing, end My Init");
super.init();//應(yīng)用了struts,此方法不能省,ActionServlet覆蓋了的此方法中有很多重要操作
}
}
我們可以看到 在此類中 用了相對路徑來加載xml的方法,首先通過prefix 讀取了項(xiàng)目的路徑然后再通過讀取web.xml中的log4j變量,獲得log4j.xml的相對路徑 兩者結(jié)合 就是他的絕對路徑拉
最后在web.xml中配置action信息 就可以實(shí)現(xiàn)加載啦
web.xml
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
com.asiainfo.ExtendedActionServlet
</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<!-- tsExtend -->
<init-param>
<param-name>config/tsextend</param-name><!--設(shè)備檢測子模塊-->
<param-value>
/WEB-INF/tsextend/struts-config.xml
</param-value>
</init-param>
<init-param>
<param-name>log4j</param-name><!--log4j.xml的路徑-->
<param-value>
/WEB-INF/log4j.xml
</param-value>
</init-param>
<init-param>
<param-name>info</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>3</param-value>
</init-param>
<load-on-startup>0</load-on-startup><!--設(shè)置當(dāng)工程初始時(shí)便執(zhí)行-->
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
依據(jù)各個(gè)級別的日志輸出到不同文件
log4j支持這個(gè)功能,不過不能再使用Properties配置,必須使用XML
建一個(gè)log4j.xml
<?xml version= "1.0 " encoding= "UTF-8 "?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd ">
<log4j:configuration xmlns:log4j= "http://jakarta.apache.org/log4j/ ">
<appender name= "STDOUT " class= "org.apache.log4j.ConsoleAppender ">
<layout class= "org.apache.log4j.PatternLayout "/>
</appender>
<appender name= "DEBUG " class= "org.apache.log4j.RollingFileAppender ">
<param name= "File " value= "debug.log "/>
<param name= "Append " value= "true "/>
<param name= "MaxFileSize " value= "500KB "/>
<param name= "MaxBackupIndex " value= "2 "/>
<layout class= "org.apache.log4j.PatternLayout "/>
<filter class= "org.apache.log4j.varia.LevelRangeFilter ">
<param name= "LevelMax " value= "DEBUG " />
<param name= "LevelMin " value= "DEBUG " />
</filter>
</appender>
<appender name= "INFO " class= "org.apache.log4j.RollingFileAppender ">
<param name= "File " value= "info.log "/>
<param name= "Append " value= "true "/>
<param name= "MaxFileSize " value= "500KB "/>
<param name= "MaxBackupIndex " value= "2 "/>
<layout class= "org.apache.log4j.PatternLayout "/>
<filter class= "org.apache.log4j.varia.LevelRangeFilter ">
<param name= "LevelMax " value= "INFO " />
<param name= "LevelMin " value= "INFO " />
</filter>
</appender>
<root>
<appender-ref ref= "STDOUT "/>
<appender-ref ref= "DEBUG "/>
<appender-ref ref= "INFO "/>
</root>
</log4j:configuration>
代碼中DOMConfigurator.configure( "log4j.xml ");
這樣就可以在log.debug和log.info時(shí)分別打印到不同文件中,如果你還需要更多的文件,可以復(fù)制多幾次appender就可以了
(1). 輸出方式appender一般有5種:
org.apache.log4j.RollingFileAppender(滾動(dòng)文件,自動(dòng)記錄最新日志)
org.apache.log4j.ConsoleAppender (控制臺)
org.apache.log4j.FileAppender (文件)
org.apache.log4j.DailyRollingFileAppender (每天產(chǎn)生一個(gè)日志文件)
org.apache.log4j.WriterAppender (將日志信息以流格式發(fā)送到任意指定的地方)
(2). 日記記錄的優(yōu)先級priority,優(yōu)先級由高到低分為
OFF ,FATAL ,ERROR ,WARN ,INFO ,DEBUG ,ALL。
Log4j建議只使用FATAL ,ERROR ,WARN ,INFO ,DEBUG這五個(gè)級別。
(3). 格式說明layout中的參數(shù)都以%開始,后面不同的參數(shù)代表不同的格式化信息(參數(shù)按字母表順序列出):
%c 輸出所屬類的全名,可在修改為 %d{Num} ,Num類名輸出的維(如:"org.apache.elathen.ClassName",%C{2}將輸出elathen.ClassName)
%d 輸出日志時(shí)間其格式為 %d{yyyy-MM-dd HH:mm:ss,SSS},可指定格式 如 %d{HH:mm:ss}
%l 輸出日志事件發(fā)生位置,包括類目名、發(fā)生線程,在代碼中的行數(shù)
%n 換行符
%m 輸出代碼指定信息,如info(“message”),輸出message
%p 輸出優(yōu)先級,即 FATAL ,ERROR 等
%r 輸出從啟動(dòng)到顯示該log信息所耗費(fèi)的毫秒數(shù)
%t 輸出產(chǎn)生該日志事件的線程名
posted @ 2011-10-09 15:40 云云 閱讀(20461) | 評論 (0) | 編輯 收藏
posted @ 2011-08-02 22:31 云云 閱讀(12842) | 評論 (0) | 編輯 收藏