|
摘要: 1.前言
Maven,發音是[`meivin],"專家"的意思。它是一個很好的項目管理工具,很早就進入了我的必備工具行列,但是這次為了把project1項目完全遷移并應用maven,所以對maven進行了一些深入的學習。寫這個學習筆記的目的,一個是為了自己備忘,二則希望能夠為其他人學習使用maven 縮短一些時間。
2. maven概要
首先我把maven的概念快速的梳理一下,讓我們快速地建... 閱讀全文
關于Hessian協議
有個同行問了這個問題,問題請參見下面鏈接 http://www.3atesting.com/bbs/vie ... &extra=page%3D1程序登陸和我們常用的http協議相似,都是通過網頁進行操作!但是實際上他的應用是采用Hessian協議進行交互!所以看到 腳本中很多都是二進制代碼!那么什么是Hessian協議呢 目前,Web服務技術是解決異構平臺系統的集成及互操作問題的主流技術[1]。它所基于的XML已經是Internet上交換數據的實際標準,基于通用的進程間通信協議和網絡傳輸協議屏蔽平臺的差異,可以將各種異構環境下的通信及調用請求均統一為標準的Web服務格式[3]。 但是由于SOAP協議的結構問題會使封裝的數據膨脹數倍。當傳輸數據量比較小時,問題不是那么明顯,但是當進行大數據量傳輸時就會導致Web服務的傳輸性能在實際運用中降低了很多。這對于經常有大數據量數據交換的應用系統來說是不適用的。 Caucho Technology公司制定的HBWSP(Hessian Binary Web Service Protocol)[2]在這方面的有所突破。Hessian協議和 web service常用的SOAP協議類似,也是將協議報文封裝在HTTP封包中,通過HTTP信道進行傳輸的。因此Hessian協議具有與SOAP協議同樣的優點,即傳輸不受防火墻的限制(防火墻通常不限制HTTP信道)。Hessian協議的優勢在于:它把本地格式的數據編碼為二進制數據,僅用一個字符作為結構化標記,HBWSP封裝后的數據增量明顯小于SOAP封裝后的數據增量。并且相對于SOAP,Hessian協議的外部數據表示有3個顯著的優勢: 1)采用簡單的結構化標記。簡單的結構化標記減少了編碼、解碼操作對內存的占用量。編碼時,只需寫少量的數據,就可以標記結構;解碼時,只需讀少量的數據就可以確定結構。而且,簡單的結構化標記減少了編碼后的數據增量。 2)采用定長的字節記錄值。用定長的字節記錄值,解碼時,就可以使用位操作從固定長度的位獲得值。這樣不僅操作簡單,而且可以獲得較高的性能。 3)采用引用取代重復遇到的對象。使用引用取代重復遇到的對象可以避免對重復對象的編碼,而且也減少了編碼后的數據量。 因此使用Hessian協議傳輸數據量比SOAP協議要小得多。實踐證明,傳輸同樣的對象Hessian協議傳輸的數據量比SOAP協議低一個數量級。因此Hessian協議比SOAP協議更適用于分布式應用系統間大數據量的數據交換。 4.2 Hessian協議的實現構架 Hessian協議的實現構架如圖3所示:為了實現Hessian 構架,設計了下列組件:編碼組件、解碼組件、通信組件、報告故障組件、代理組件、調用服務過程組件。  圖3 Hessian協議的實現構架 首先客戶端發出本地請求,代理組件響應請求依據服務接口,生成客戶端存根,并調用編碼組件對本地請求進行基于Hessian Binary Web Service Protocol標準的二進制編碼。然后調用通信組件將請求發送給服務器端。服務器端通信組件接收到請求后把請求轉發給調用服務過程組件,調用服務過程組件會首先調用解碼組件,得到過程標識,將過程標識轉給服務器端存根,并依據部署文件和客戶端的請求加載服務過程的實現類。然后根據過程標識、過程參數調用服務過程。最后調用編碼組件將響應結果進行編碼并通過通信組件返回給客戶端。 當數據傳輸、通信發生錯誤的時候就需要啟用報告故障組件,它可以以異常的形式,報告發送端、接收端、或者網絡連接發生的故障,并把錯誤記錄以日志的方式記錄下來保存在文件中,以備日后查閱。 4.3 實現結構 針對教務管理系統互聯網傳輸存在的一系列問題,基于互聯網的主體數據平臺采用基于HBWSP的輕量級跨平臺通信技術實現數據交換,如圖4所示。在客戶端,應用服務器從主題數據服務層中抽取數據,并按著HBWSP的外部數據表示對本地格式數據進行編碼。然后通過internet網進行傳輸,在服務器端,數據交換的服務負責按照HBWSP的外部數據表示對接收到的數據進行解碼,然后再對數據進行分析、處理后把數據插入到服務器端的主題數據服務層中。  圖4非持久同步方式的數據交換解決方案 該解決方案的主要特點包括: 1)采用了HBWSP的二進制編碼方式解決了異地、異構平臺系統的通信問題,并使數據交互具有了一定的實時性。 2)由于HBWSP簡潔的編碼方式以及編碼、解碼性能高等特點使數據交換具有交換GB級數據的能力。 3)采用了HBWSP的二進制編碼方式有助于縮短整個數據交換所需要的時間。其編碼性能高的特點,有助于提高編碼速度,減少發送方編碼本地數據的時間。其解碼性能高的特點,可以減少接收方解碼、重構本地數據的時間。從而減少了數據交換的響應時間。 4)采用了HBWSP的二進制編碼方式和數據分批傳送技術有助于充分利用網絡狀況良好的時段??梢栽诰W絡狀況良好的時段盡可能多的完成數據交換。 5)采用了斷點續傳技術,保證了當網絡斷連或響應超時導致正在進行的數據交換被中斷,在故障修復后仍然可以從中斷處開始,繼續完成上次沒有完成的數據交換的能力。斷點的粒度可以調節,可以是一條數據,也可以是多條數據。 6)采用了事務保護機制,把每批要傳輸的數據定義為一個事務,本批要傳輸的數據的事務完整性不依賴于已經完成的各批數據,本批數據傳輸發生錯誤也不會對已經完成的各批數據造成影響。采用這種方法,可以在數據交換過程被中斷的情況下保證數據交換事務的完整性。
List <Integer> list = new ArrayList <Integer>();
Map <Integer,Integer> map = new HashMap <Integer,Integer>();
 for(Integer i :list) {
map.put(i, map.get(i)+1);
}把list集合中的數據 循環放進map中 如果當前元素已經在map中了 就加1 第二種方法:
 public class Test2 {
 public static void main(String [] args) {
List<Integer> myList=Arrays.asList(1,1,2,2,3,3,3,4,4);
HashSet<Integer> hs=new HashSet<Integer>(myList);
 for(Integer i:hs) {
System.out.println(i+" 在List中存在" + Collections.frequency(myList,i) + "個");
}
}
}
一、cookie機制和session機制的區別 具體來說cookie機制采用的是在客戶端保持狀態的方案,而session機制采用的是在服務器端保持狀態的方案。 同時我們也看到,由于在服務器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制可能需要借助于cookie機制來達到保存標識的目的,但實際上還有其他選擇。
二、會話cookie和持久cookie的區別 如果不設置過期時間,則表示這個cookie生命周期為瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了。這種生命期為瀏覽會話期的cookie被稱為會話cookie。會話cookie一般不保存在硬盤上而是保存在內存里。 如果設置了過期時間,瀏覽器就會把cookie保存到硬盤上,關閉后再次打開瀏覽器,這些cookie依然有效直到超過設定的過期時間。 存儲在硬盤上的cookie可以在不同的瀏覽器進程間共享,比如兩個IE窗口。而對于保存在內存的cookie,不同的瀏覽器有不同的處理方式。
三、如何利用實現自動登錄 當用戶在某個網站注冊后,就會收到一個惟一用戶ID的cookie。客戶后來重新連接時,這個用戶ID會自動返回,服務器對它進行檢查,確定它是否為注冊用戶且選擇了自動登錄,從而使用戶無需給出明確的用戶名和密碼,就可以訪問服務器上的資源。
四、如何根據用戶的愛好定制站點 網站可以使用cookie記錄用戶的意愿。對于簡單的設置,網站可以直接將頁面的設置存儲在cookie中完成定制。然而對于更復雜的定制,網站只需僅將一個惟一的標識符發送給用戶,由服務器端的數據庫存儲每個標識符對應的頁面設置。
五、cookie的發送 1.創建Cookie對象 2.設置最大時效 3.將Cookie放入到HTTP響應報頭 如果你創建了一個cookie,并將他發送到瀏覽器,默認情況下它是一個會話級別的cookie:存儲在瀏覽器的內存中,用戶退出瀏覽器之后被刪除。如果你希望瀏覽器將該cookie存儲在磁盤上,則需要使用maxAge,并給出一個以秒為單位的時間。將最大時效設為0則是命令瀏覽器刪除該 cookie。 發送cookie需要使用HttpServletResponse的addCookie方法,將cookie插入到一個 Set-Cookie HTTP請求報頭中。由于這個方法并不修改任何之前指定的Set-Cookie報頭,而是創建新的報頭,因此我們將這個方法稱為是addCookie,而非setCookie。同樣要記住響應報頭必須在任何文檔內容發送到客戶端之前設置。
六、cookie的讀取 1.調用request.getCookie 要獲取有瀏覽器發送來的cookie,需要調用HttpServletRequest的getCookies方法,這個調用返回Cookie對象的數組,對應由HTTP請求中Cookie報頭輸入的值。 2.對數組進行循環,調用每個cookie的getName方法,直到找到感興趣的cookie為止 cookie與你的主機(域)相關,而非你的servlet或JSP頁面。因而,盡管你的servlet可能只發送了單個cookie,你也可能會得到許多不相關的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.調用HttpServletRequest.getCookies()獲取Cookie數組 B.在循環中檢索指定名字的cookie是否存在以及對應的值是否正確 C.如果是則退出循環并設置區別標識 D.根據區別標識判斷用戶是否為初訪者從而進行不同的操作
八、使用cookie檢測初訪者的常見錯誤 不能僅僅因為cookie數組中不存在在特定的數據項就認為用戶是個初訪者。如果cookie數組為null,客戶可能是一個初訪者,也可能是由于用戶將cookie刪除或禁用造成的結果。 但是,如果數組非null,也不過是顯示客戶曾經到過你的網站或域,并不能說明他們曾經訪問過你的servlet。其它servlet、JSP頁面以及非Java Web應用都可以設置cookie,依據路徑的設置,其中的任何cookie都有可能返回給用戶的瀏覽器。 正確的做法是判斷cookie數組是否為空且是否存在指定的Cookie對象且值正確。
九、使用cookie屬性的注意問題 屬性是從服務器發送到瀏覽器的報頭的一部分;但它們不屬于由瀏覽器返回給服務器的報頭?!?br /> 因此除了名稱和值之外,cookie屬性只適用于從服務器輸出到客戶端的cookie;服務器端來自于瀏覽器的cookie并沒有設置這些屬性?!?br /> 因而不要期望通過request.getCookies得到的cookie中可以使用這個屬性。這意味著,你不能僅僅通過設置cookie的最大時效,發出它,在隨后的輸入數組中查找適當的cookie,讀取它的值,修改它并將它存回Cookie,從而實現不斷改變的cookie值。
十、如何使用cookie記錄各個用戶的訪問計數 1.獲取cookie數組中專門用于統計用戶訪問次數的cookie的值 2.將值轉換成int型 3.將值加1并用原來的名稱重新創建一個Cookie對象 4.重新設置最大時效 5.將新的cookie輸出
十一、session在不同環境下的不同含義 session,中文經常翻譯為會話,其本來的含義是指有始有終的一系列動作/消息,比如打電話是從拿起電話撥號到掛斷電話這中間的一系列過程可以稱之為一個session。 然而當session一詞與網絡協議相關聯時,它又往往隱含了“面向連接”和/或“保持狀態”這樣兩個含義。 session在Web開發環境下的語義又有了新的擴展,它的含義是指一類用來在客戶端與服務器端之間保持狀態的解決方案。有時候Session也用來指這種解決方案的存儲結構。
十二、session的機制 session機制是一種服務器端的機制,服務器使用一種類似于散列表的結構(也可能就是使用散列表)來保存信息。 但程序需要為某個客戶端的請求創建一個session的時候,服務器首先檢查這個客戶端的請求里是否包含了一個session標識-稱為session id,如果已經包含一個session id則說明以前已經為此客戶創建過session,服務器就按照session id把這個session檢索出來使用(如果檢索不到,可能會新建一個,這種情況可能出現在服務端已經刪除了該用戶對應的session對象,但用戶人為地在請求的URL后面附加上一個JSESSION的參數)。 如果客戶請求不包含session id,則為此客戶創建一個session并且生成一個與此session相關聯的session id,這個session id將在本次響應中返回給客戶端保存。
十三、保存session id的幾種方式 A.保存session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動的按照規則把這個標識發送給服務器。 B.由于cookie可以被人為的禁止,必須有其它的機制以便在cookie被禁止時仍然能夠把session id傳遞回服務器,經常采用的一種技術叫做URL重寫,就是把session id附加在URL路徑的后面,附加的方式也有兩種,一種是作為URL路徑的附加信息,另一種是作為查詢字符串附加在URL后面。網絡在整個交互過程中始終保持狀態,就必須在每個客戶端可能請求的路徑后面都包含這個session id。 C.另一種技術叫做表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時能夠把session id傳遞回服務器。
十四、session什么時候被創建 一個常見的錯誤是以為session在有客戶端訪問時就被創建,然而事實是直到某server端程序(如Servlet)調用HttpServletRequest.getSession(true)這樣的語句時才會被創建。
十五、session何時被刪除 session在下列情況下被刪除: A.程序調用HttpSession.invalidate() B.距離上一次收到客戶端發送的session id時間間隔超過了session的最大有效時間 C.服務器進程被停止 再次注意關閉瀏覽器只會使存儲在客戶端瀏覽器內存中的session cookie失效,不會使服務器端的session對象失效。
十六、URL重寫有什么缺點 對所有的URL使用URL重寫,包括超鏈接,form的action,和重定向的URL。每個引用你的站點的URL,以及那些返回給用戶的URL(即使通過間接手段,比如服務器重定向中的Location字段)都要添加額外的信息。 這意味著在你的站點上不能有任何靜態的HTML頁面(至少靜態頁面中不能有任何鏈接到站點動態頁面的鏈接)。因此,每個頁面都必須使用servlet或 JSP動態生成。即使所有的頁面都動態生成,如果用戶離開了會話并通過書簽或鏈接再次回來,會話的信息都會丟失,因為存儲下來的鏈接含有錯誤的標識信息-該URL后面的SESSION ID已經過期了?! ?/p>
十七、使用隱藏的表單域有什么缺點 僅當每個頁面都是有表單提交而動態生成時,才能使用這種方法。單擊常規的<A HREF..>超文本鏈接并不產生表單提交,因此隱藏的表單域不能支持通常的會話跟蹤,只能用于一系列特定的操作中,比如在線商店的結賬過程。
十八、會話跟蹤的基本步驟 1.訪問與當前請求相關的會話對象 2.查找與會話相關的信息 3.存儲會話信息 4.廢棄會話數據
十九、getSession()/getSession(true)、getSession(false)的區別 getSession()/getSession(true):當session存在時返回該session,否則新建一個session并返回該對象 getSession(false):當session存在時返回該session,否則不會新建session,返回null
二十、如何將信息與會話關聯起來 setAttribute會替換任何之前設定的值;如果想要在不提供任何代替的情況下移除某個值,則應使用removeAttribute。這個方法會觸發所有實現了HttpSessionBindingListener接口的值的valueUnbound方法。
二十一、會話屬性的類型有什么限制嗎 通常會話屬性的類型只要是Object就可以了。除了null或基本類型,如int,double,boolean。 如果要使用基本類型的值作為屬性,必須將其轉換為相應的封裝類對象
二十二、如何廢棄會話數據 A.只移除自己編寫的servlet創建的數據: 調用removeAttribute(“key”)將指定鍵關聯的值廢棄 B.刪除整個會話(在當前Web應用中): 調用invalidate,將整個會話廢棄掉。這樣做會丟失該用戶的所有會話數據,而非僅僅由我們servlet或JSP頁面創建的會話數據 C.將用戶從系統中注銷并刪除所有屬于他(或她)的會話 調用logOut,將客戶從Web服務器中注銷,同時廢棄所有與該用戶相關聯的會話(每個Web應用至多一個)。這個操作有可能影響到服務器上多個不同的Web應用。
二十三、使用isNew來判斷用戶是否為新舊用戶的錯誤做法 public boolean isNew()方法如果會話尚未和客戶程序(瀏覽器)發生任何聯系,則這個方法返回true,這一般是因為會話是新建的,不是由輸入的客戶請求所引起的。 但如果isNew返回false,只不過是說明他之前曾經訪問該Web應用,并不代表他們曾訪問過我們的servlet或JSP頁面。 因為session是與用戶相關的,在用戶之前訪問的每一個頁面都有可能創建了會話。因此isNew為false只能說用戶之前訪問過該Web應用,session可以是當前頁面創建,也可能是由用戶之前訪問過的頁面創建的。 正確的做法是判斷某個session中是否存在某個特定的key且其value是否正確
二十四、Cookie的過期和Session的超時有什么區別 會話的超時由服務器來維護,它不同于Cookie的失效日期。首先,會話一般基于駐留內存的cookie不是持續性的cookie,因而也就沒有截至日期。即使截取到JSESSIONID cookie,并為它設定一個失效日期發送出去。瀏覽器會話和服務器會話也會截然不同。
二十五、session cookie和session對象的生命周期是一樣的嗎 當用戶關閉了瀏覽器雖然session cookie已經消失,但session對象仍然保存在服務器端
二十六、是否只要關閉瀏覽器,session就消失了 程序一般都是在用戶做log off的時候發個指令去刪除session,然而瀏覽器從來不會主動在關閉之前通知服務器它將要被關閉,因此服務器根本不會有機會知道瀏覽器已經關閉。服務器會一直保留這個會話對象直到它處于非活動狀態超過設定的間隔為止。 之所以會有這種錯誤的認識,是因為大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器后這個session id就消失了,再次連接到服務器時也就無法找到原來的session。 如果服務器設置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發出的HTTP請求報頭,把原來的session id發送到服務器,則再次打開瀏覽器仍然能夠找到原來的session。 恰恰是由于關閉瀏覽器不會導致session被刪除,迫使服務器為session設置了一個失效時間,當距離客戶上一次使用session的時間超過了這個失效時間時,服務器就可以認為客戶端已經停止了活動,才會把session刪除以節省存儲空間。 由此我們可以得出如下結論: 關閉瀏覽器,只會是瀏覽器端內存里的session cookie消失,但不會使保存在服務器端的session對象消失,同樣也不會使已經保存到硬盤上的持久化cookie消失。
二十七、打開兩個瀏覽器窗口訪問應用程序會使用同一個session還是不同的session 通常session cookie是不能跨窗口使用的,當你新開了一個瀏覽器窗口進入相同頁面時,系統會賦予你一個新的session id,這樣我們信息共享的目的就達不到了。 此時我們可以先把session id保存在persistent cookie中(通過設置session的最大有效時間),然后在新窗口中讀出來,就可以得到上一個窗口的session id了,這樣通過session cookie和persistent cookie的結合我們就可以實現了跨窗口的會話跟蹤。
二十八、如何使用會話顯示每個客戶的訪問次數 由于客戶的訪問次數是一個整型的變量,但session的屬性類型中不能使用int,double,boolean等基本類型的變量,所以我們要用到這些基本類型的封裝類型對象作為session對象中屬性的值 但像Integer是一種不可修改(Immutable)的數據結構:構建后就不能更改。這意味著每個請求都必須創建新的Integer對象,之后使用setAttribute來代替之前存在的老的屬性的值。例如: HttpSession session = request.getSession(); SomeImmutalbeClass value = (SomeImmutableClass)session.getAttribute(“SomeIdentifier”); if (value= =null){ value = new SomeImmutableClass(…); // 新創建一個不可更改對象 }else{ value = new SomeImmutableClass(calculatedFrom(value)); // 對value重新計算后創建新的對象 } session.setAttribute(“someIdentifier”,value); // 使用新創建的對象覆蓋原來的老的對象
二十九、如何使用會話累計用戶的數據 使用可變的數據結構,比如數組、List、Map或含有可寫字段的應用程序專有的數據結構。通過這種方式,除非首次分配對象,否則不需要調用setAttribute。例如 HttpSession session = request.getSession(); SomeMutableClass value = (SomeMutableClass)session.getAttribute(“someIdentifier”); if(value = = null){ value = new SomeMutableClass(…); session.setAttribute(“someIdentifier”,value); }else{ value.updateInternalAttribute(…); // 如果已經存在該對象則更新其屬性而不需重新設置屬性 }
三十、不可更改對象和可更改對象在會話數據更新時的不同處理 不可更改對象因為一旦創建之后就不能更改,所以每次要修改會話中屬性的值的時候,都需要調用 setAttribute(“someIdentifier”,newValue)來代替原有的屬性的值,否則屬性的值不會被更新可更改對象因為其自身一般提供了修改自身屬性的方法,所以每次要修改會話中屬性的值的時候,只要調用該可更改對象的相關修改自身屬性的方法就可以了。這意味著我們就不需要調用 setAttribute方法了。
使過更新sdk 也沒用 最后在dos中輸入adb 還是 顯示 不是內部命令 最后google一下 發現有人提供了方法 大謝
找到你的android-sdk-windows\platform-tools目錄,打開后會發現里面有許多文件。
找到adb.exe,AdbWinApi.dll,AdbWinUsbApi.dll這三個文件,將這三個文件拷到你android-sdk-windows\tools目錄下。 試用成功
Android 在開發中會自動生成一個 R.java 文件 ,這個文件是自動生成的,最好不要去改。不過有時候這個 java 文件會跟我們捉迷藏,在程序中 R.xx.xxx 會出現經常報錯現象。 1 對著工程點擊鼠標右鍵 選擇 Build Project,R.java 文件又回來。這樣R.xx.xxx 就能 X 的出來了。 如果不行 試用第二種 方法
2 選擇eclipse/myeclipse 的 clean 這樣R文件也會出現 如果還不行 試用第三種
3 經過上面兩種方法都不行 使用絕招 從別的工程中拷貝一份R文件過來 然后string.xml里隨便改動一下 即可更新R文件 如果還不行 試用第四種
4 經過上面的3種方法都不行 說明我們的工程有問題 好好檢查吧 比如resoure資源中的文件 命名,例result_main.xml,如果寫成Result_main.xml是錯誤的 需要全部小寫
一直用myeclipse習慣了 剛開始學android的時候 用eclipse裝adt 但是用同樣的方法在myeclipse上裝adt的插件時 就不好用 在網上找了很久 找到了這份記錄 就摘過來了 一起分享 呵呵 原文: http://blog.csdn.net/paulluo0739/article/details/6656516
使用MyEclipse8.5的自動加載組件功能,會把原本的J2EE插件給干掉,實在是可氣,造成adt加上了,但J2EE不能用的尷尬狀況。卸載之后使用手動添加adt插件的方法可避免該問題。
1、下載最新的adt插件ADT-10.0.1.zip
2、zip解壓出plugins下的四個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、復制到MyEclipse8.5的\Common\plugins目錄下
4、修改MyEclipse 8.5\configuration\org.eclipse.equinox.simpleconfigurator目錄下的bundles.info文件,添加以下內容:
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
個人的安裝方法如下:
1.首先下載SVN包:site -1.6.17 http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240
2.解壓SVN包,然后找到其中的兩個文件夾:features 和 plugins
3.隨意建一個文件夾(位置和名稱自己定就好了,我的是E:\myEclipsePlugin\svn),然后把第二步的解壓好的features 和 plugins放到這個文件夾下
4.找到myeclipse的安裝目錄,下面有一個configuration\org.eclipse.equinox.simpleconfigurator\bundles.info 文件?,F在需要做的就是在該文件內添加的東西
5.添加的內容用下面的類生成:
 import java.io.File; import java.util.ArrayList; import java.util.List; /** *//** * MyEclipse9 插件配置代碼生成器 * * */ public class PluginConfigCreator { public PluginConfigCreator() { } public void print(String path) { List<String> list = getFileList(path); if (list == null) { return; } int length = list.size(); for (int i = 0; i < length; i++) { String result = ""; String thePath = getFormatPath(getString(list.get(i))); File file = new File(thePath); if (file.isDirectory()) { String fileName = file.getName(); if (fileName.indexOf("_") < 0) { print(thePath); continue; } String[] filenames = fileName.split("_"); String filename1 = filenames[0]; String filename2 = filenames[1]; result = filename1 + "," + filename2 + ",file:/" + path + "/" + fileName + "\\,4,false"; System.out.println(result); } else if (file.isFile()) { String fileName = file.getName(); if (fileName.indexOf("_") < 0) { continue; } int last = fileName.lastIndexOf("_");// 最后一個下劃線的位置 String filename1 = fileName.substring(0, last); String filename2 = fileName.substring(last + 1, fileName .length() - 4); result = filename1 + "," + filename2 + ",file:/" + path + "/" + fileName + ",4,false"; System.out.println(result); } } } public List<String> getFileList(String path) { path = getFormatPath(path); path = path + "/"; File filePath = new File(path); if (!filePath.isDirectory()) { return null; } String[] filelist = filePath.list(); List<String> filelistFilter = new ArrayList<String>(); for (int i = 0; i < filelist.length; i++) { String tempfilename = getFormatPath(path + filelist[i]); filelistFilter.add(tempfilename); } return filelistFilter; } public String getString(Object object) { if (object == null) { return ""; } return String.valueOf(object); } public String getFormatPath(String path) { path = path.replaceAll("\\\\", "/"); path = path.replaceAll("//", "/"); return path; } public static void main(String[] args) { /*你的SVN的features 和 plugins復制后放的目錄*/ String plugin = "E:/myEclipsePlugin/svn/"; new PluginConfigCreator().print(plugin); } }

如果把svn文件放在了這個位置 就不用動行上面的java代碼了 因為我已經運行過一次了 下面把生成的東東貼出來 就可以直接用了
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即可。
由于項目中使用的log4j.xml這種配置 在網上找到這份介紹較全的 就摘錄下來 一起分享
使用log4j
獲取logger Logger.getRootLogger() 獲取根logger Logger.getLogger(String name)獲取子logger Logger.getLogger(Class clazz)或 Logger.getLogger(clazz.getName())
設置日志級別(.setLevel(int,Exception)) Level.ALL打開所有日志 Level.DEBUG 用于調試 Level.INFO 用于運行過程 Level.WARN 用于潛在的錯誤 Level.ERROR 用于錯誤事件 Level.FATAL 用于嚴重錯誤時間 Level.OFF 關閉所有日志
輸出端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 輸出到文件,每天一個新文件 org.apache.log4j.RollingFileAppender 輸出到文件,自動新增改名 public RollingFileAppender(Layout,String fileName) void setMaxBackupIndex(int index) 設置日志文件最大備份數 void setMaximumFileSize(long size) 設置日志文件最大尺寸 org.apache.log4j.WriterAppender 流格式輸出到任意地方 org.apache.log4j.JDBCAppender 輸出到數據庫
日志格式化(Layout) %c 類全名 %d 時間 %f 類名 %l 位置 %m 信息 %n 換行 %p 級別 %r 耗時 %t 線程名
public PatternLayout() 使用默認設置DEFAULT_CONVERSION_PATTERN 只打印信息 public PatternLayout(String)使用自定義的pattern構造一個PatternLayout void setConversionPattern(String) 設置日志格式 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 設置級別和三個輸出端 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 目標文件 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 目標文件 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 驅動 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>
應用 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時才注意log4j.xml,原來一直使用log4j.properties,發現它比properties功能強大,可以配置輸出多個log文件。 轉一個基本的配置:
log4j 有兩種配置方法,大家熟知的是properties文件但是最近的項目實施中,每次去用戶那里裝系統,都要苦惱于log文件放在不同位置,要改property文件就要重打jar包,麻煩的緊。而如果采用xml配置的方法,直接放在WEB-INFO下,要修改路徑,很方便。查了些資料,終于把系統的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"> <!-- 設置通道file和輸出方式:org.apache.log4j.RollingFileAppender --> <param name="File" value="D:/zhaotj/all.output.log" /><!-- 設置File參數:日志輸出文件名 --> <param name="Append" value="true" /><!-- 設置是否在重新啟動服務時,在原有日志的基礎添加新日志 --> <param name="MaxBackupIndex" value="10" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%p (%c:%L)- %m%n" /><!-- 設置輸出文件項目和格式 --> </layout> </appender>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <!-- 設置監視器輸出方式 --> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-4r [%t] %-5p %c %x - %m%n" /> </layout> <!--濾鏡設置輸出的級別--> <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><!-- 設置接收所有輸出的通道 --> <priority value="info" /> <appender-ref ref="FILE" /><!-- 與前面的通道id相對應 --> <appender-ref ref="STDOUT" /> </root>
</log4j:configuration> 建好xml文件后 要寫一個servlet類繼承actionservlet,當工程初始化時自動加載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( "/");//讀取項目的路徑 String file = this.getServletConfig().getInitParameter("log4j"); //讀取log4j相對路徑 String filePath = prefix + file; DOMConfigurator.configure(filePath);//加載.xml文件 log.info("Initializing, end My Init"); super.init();//應用了struts,此方法不能省,ActionServlet覆蓋了的此方法中有很多重要操作 } } 我們可以看到 在此類中 用了相對路徑來加載xml的方法,首先通過prefix 讀取了項目的路徑然后再通過讀取web.xml中的log4j變量,獲得log4j.xml的相對路徑 兩者結合 就是他的絕對路徑拉 最后在web.xml中配置action信息 就可以實現加載啦 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><!--設備檢測子模塊--> <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><!--設置當工程初始時便執行--> </servlet>
<servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
依據各個級別的日志輸出到不同文件
log4j支持這個功能,不過不能再使用Properties配置,必須使用XML
建一個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時分別打印到不同文件中,如果你還需要更多的文件,可以復制多幾次appender就可以了 (1). 輸出方式appender一般有5種:
org.apache.log4j.RollingFileAppender(滾動文件,自動記錄最新日志) org.apache.log4j.ConsoleAppender (控制臺) org.apache.log4j.FileAppender (文件) org.apache.log4j.DailyRollingFileAppender (每天產生一個日志文件) org.apache.log4j.WriterAppender (將日志信息以流格式發送到任意指定的地方)
(2). 日記記錄的優先級priority,優先級由高到低分為 OFF ,FATAL ,ERROR ,WARN ,INFO ,DEBUG ,ALL。 Log4j建議只使用FATAL ,ERROR ,WARN ,INFO ,DEBUG這五個級別。
(3). 格式說明layout中的參數都以%開始,后面不同的參數代表不同的格式化信息(參數按字母表順序列出): %c 輸出所屬類的全名,可在修改為 %d{Num} ,Num類名輸出的維(如:"org.apache.elathen.ClassName",%C{2}將輸出elathen.ClassName) %d 輸出日志時間其格式為 %d{yyyy-MM-dd HH:mm:ss,SSS},可指定格式 如 %d{HH:mm:ss} %l 輸出日志事件發生位置,包括類目名、發生線程,在代碼中的行數 %n 換行符 %m 輸出代碼指定信息,如info(“message”),輸出message %p 輸出優先級,即 FATAL ,ERROR 等 %r 輸出從啟動到顯示該log信息所耗費的毫秒數 %t 輸出產生該日志事件的線程名
摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->package com.alimama.common.util;import java.text.DateFormat;import java.text.SimpleDate... 閱讀全文
|