積少成多

          垃圾堆

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            29 Posts :: 1 Stories :: 5 Comments :: 0 Trackbacks

          #

          Flex Builder 3 正式版,發布于中國時間 2008 年 2 月 25 日;

          下載地址一:
          http://download.macromedia.com/pub/flex/flex_builder/FB3_win.exe
          大小: 424 MB ;未進行壓縮的 Flex Builder 3 安裝文件
          不用注冊登錄,可以直接下載。

          下載地址二:

          http://trials.adobe.com/Applications/.../FB3_WWEJ.exe
          大小: 385.84 MB ; 已經壓縮的 Flex Builder 3 安裝文件
          需要注冊登錄,才可下載。

          Flex builder 3.0注冊碼(已經試過的,可用的):

          1377-4168-2018-0771-2432-1495

          1377-4760-3354-0772-2773-8996

          1377-4165-2080-7265-7813-8901

          1377-4964-5021-8182-2399-8235

          Flex builder 中要進行調試,就必須安裝含debug的flash player版本。下載鏈接地址:

          Adobe Flash Player 9 — Debugger Versions (aka debug players or content debuggers) for Flex and Flash Developers

          12/3/2007 Updated debugger versions of Flash Player 9 (aka debug players or content debuggers) are available for Flex Builder 2 users and Flash CS3 Professional users. These new players are version 9.0.r115.

          Download the Windows Flash Player 9 ActiveX control content debugger (for IE) (EXE, 1.59 MB)

          Download the Windows Flash Player 9 Plugin content debugger (for Netscape-compatible browsers) (EXE, 1.56 MB)

          Download the Windows Flash Player 9 Projector content debugger (EXE, 3.69 MB)

          Download the Macintosh Flash Player 9 Plugin content debugger (Intel-based Macs) (DMG, 5.35 MB)

          Download the Macintosh Flash Player 9 Plugin content debugger (PowerPC-based Macs) (DMG, 2.41 MB)

          Download the Macintosh Flash Player 9 Projector content debugger (ZIP, 4.81 MB)

          12/3/2007 Updated Linux debugger versions (aka debug players or content debuggers) of Flash Player 9 are now available. Additionally, the Linux standalone player (projector) is available for developers who wish to publish projectors on Linux operating systems.

          Download the Linux debugger and standalone players (TAR.GZ, 9.29 MB)

          posted @ 2011-06-28 22:46 思無 閱讀(378) | 評論 (0)編輯 收藏

          項目中,瀏覽器和服務器之間長時間沒有交互,會被超時,但是用戶只有在下次嘗試連接的時候才會知道已經超時了。總結了一下當前這個項目針對這個問題是怎么做的。
          在即將超時的時候,提醒用戶,之后通過ajax 發送空消息給服務器以防止服務器將session無效。
          下面是核心的代碼:

          var previousSmSession = null;
          var times = 0;
          var timer = setInterval("checkSmSession()"60 * 3000);
          var maxTimes = 9;

          function checkSmSession()
          {
              
          var currentSmSession = getCurrSmSession();
              
          if (currentSmSession != previousSmSession) {
                  previousSmSession 
          = currentSmSession;
                  times 
          = 0;
              } 
          else {
                  times
          ++;
                  
          if (maxTimes == times) {
                          
          this.focus();
                          
          var currentCheckingTime = new Date();
                          currentCheckingTime.setTime(currentCheckingTime.getTime() 
          + 60 * 3000);
                          
          var sessionWarningMsg = "Due to inactivity you will be logged out of the system at " + currentCheckingTime.toLocaleString().replace(/^.*?\d{4/,""+ ". To extend your session click OK."
                          
          var val = confirm(sessionWarningMsg);
                          
          if (val) {
                                  times 
          = 0;
                                  refreshSessions();
                           } 
          else {
                                
          //  self.location = "/wps/logout.jsp"; 
                          }
                  }
              }
          }


          function getCurrSmSession() {
              
          var allCookies = document.cookie.split(";");
              
              
          var aCookie = null;
              
          var aCookieName = "";
              
          var aCookieValue = "";         
              
          for (var i=0; i<allCookies.length; i++)    {
                  aCookie 
          = allCookies[i].split("=");
                  aCookieName 
          = aCookie[0].replace(/^\s+|\s+$/g, "");
                  
          if (smSessionName == aCookieName) {
                      
          if (aCookie.length > 1) {
                          aCookieValue 
          = unescape(aCookie[1].replace(/^\s+|\s+$/g, ""));
                      }
                      
          break;
                  }
              }
              
          if (i == allCookies.length) {
                  aCookieValue 
          = null;
              }
              
          return aCookieValue;
          }

          function refreshSessions () {
              
          var dummyUrls = ["/home/FlexKeepAlive.jsp""/cfi/FlexKeepAlive.jsp"];
              
          for (var i=0; i<dummyUrls.length; i++) {
                  
          var aXmlHttp = getXMLHttpObject();
                  
          if (null == aXmlHttp) {
                      alert(
          "AJAX does not work!");
                      
          break;    
                  }
                  aXmlHttp.open(
          "GET", dummyUrls[i]+"?sid="+Math.random(), true);
                  aXmlHttp.send(
          null);
              }     
          }

          function getXMLHttpObject () {
              
          var xmlHttpObj = null;
              
              
          try {
                  xmlHttpObj 
          = new XMLHttpRequest();// Firefox    
              } catch (e) {
                  
          try {
                      xmlHttpObj 
          = new ActiveXObject("Msxml2.XMLHTTP");    //IE
                  } catch (e) {
                      xmlHttpObj 
          = new ActiveXObject("Microsoft.XMLHTTP");
                  }
              }
              
              
          return xmlHttpObj;
          }
          posted @ 2011-06-28 16:22 思無 閱讀(350) | 評論 (0)編輯 收藏

          http://www.iteye.com/topic/72170

          關于j2ee項目中異常的管理和設計。之前一直困惑于異常的處理,為什么異常分為checked和uncheck,應該遵循怎樣的規則自定義異常。在j2ee項目中,處理異常需要注意什么地方。
          [原文]
          為什么要在J2EE項目中談異常處理呢?可能許多java初學者都想說:“異常處理不就是try….catch…finally嗎?這誰都會 啊!”。筆者在初學java時也是這樣認為的。如何在一個多層的j2ee項目中定義相應的異常類?在項目中的每一層如何進行異常處理?異常何時被拋出?異 常何時被記錄?異常該怎么記錄?何時需要把checked Exception轉化成unchecked Exception ,何時需要把unChecked Exception轉化成checked Exception?異常是否應該呈現到前端頁面?如何設計一個異常框架?本文將就這些問題進行探討。
          1. JAVA異常處理
          在面向過程式的編程語言中,我們可以通過返回值來確定方法是否正常執行。比如在一個c語言編寫的程序中,如果方法正確的執行則返回1.錯誤則返回0。在vb或delphi開發的應用程序中,出現錯誤時,我們就彈出一個消息框給用戶。
          通過方法的返回值我們并不能獲得錯誤的詳細信息。可能因為方法由不同的程序員編寫,當同一類錯誤在不同的方法出現時,返回的結果和錯誤信息并不一致。
          所以java語言采取了一個統一的異常處理機制。
          什么是異常?運行時發生的可被捕獲和處理的錯誤。
          在java語言中,Exception是所有異常的父類。任何異常都擴 展于Exception類。Exception就相當于一個錯誤類型。如果要定義一個新的錯誤類型就擴展一個新的Exception子類。采用異常的好處 還在于可以精確的定位到導致程序出錯的源代碼位置,并獲得詳細的錯誤信息。
          Java異常處理通過五個關鍵字來實 現,try,catch,throw ,throws, finally。具體的異常處理結構由try….catch….finally塊來實現。try塊存放可能出現異常的java語句,catch用來捕獲發 生的異常,并對異常進行處理。Finally塊用來清除程序中未釋放的資源。不管理try塊的代碼如何返回,finally塊都總是被執行。
          一個典型的異常處理代碼
          java 代碼
          1.   
          2. public String getPassword(String userId)throws DataAccessException{   
          3. String sql = “select password from userinfo where userid=’”+userId +”’”;   
          4. String password = null;   
          5. Connection con = null;   
          6. Statement s = null;   
          7. ResultSet rs = null;   
          8. try{   
          9.  con = getConnection();//獲得數據連接   
          10.  s = con.createStatement();   
          11.  rs = s.executeQuery(sql);   
          12.  while(rs.next()){   
          13.     password = rs.getString(1);   
          14.  }   
          15.  rs.close();   
          16.  s.close();   
          17.      
          18. }   
          19. Catch(SqlException ex){   
          20.  throw new DataAccessException(ex);   
          21. }   
          22. finally{   
          23.  try{   
          24.       if(con != null){   
          25.         con.close();   
          26.       }   
          27.  }   
          28.    Catch(SQLException sqlEx){   
          29.      throw new DataAccessException(“關閉連接失敗!”,sqlEx);   
          30.    }   
          31. }   
          32. return password;   
          33. }   
          34.    
          可以看出Java的異常處理機制具有的優勢:
          給錯誤進行了統一的分類,通過擴展Exception類或其子類來實現。從而避免了相同的錯誤可能在不同的方法中具有不同的錯誤信息。在不同的方法中出現相同的錯誤時,只需要throw 相同的異常對象即可。
          獲得更為詳細的錯誤信息。通過異常類,可以給異常更為詳細,對用戶更為有用的錯誤信息。以便于用戶進行跟蹤和調試程序。
          把正確的返回結果與錯誤信息分離。降低了程序的復雜度。調用者無需要對返回結果進行更多的了解。
          強制調用者進行異常處理,提高程序的質量。當一個方法聲明需要拋出一個異常時,那么調用者必須使用try….catch塊對異常進行處理。當然調用者也可以讓異常繼續往上一層拋出。
           
          2. Checked 異常 還是 unChecked 異常?
          Java異常分為兩大類:checked 異常和unChecked 異常。所有繼承java.lang.Exception 的異常都屬于checked異常。所有繼承java.lang.RuntimeException的異常都屬于unChecked異常。
          當一個方法去調用一個可能拋出checked異常的方法,必須通過try…catch塊對異常進行捕獲進行處理或者重新拋出。
          我們看看Connection接口的createStatement()方法的聲明。
          public Statement createStatement() throws SQLException;
                
             SQLException是checked異常。當調用createStatement方法時,java強制調用者必須對SQLException進行捕獲處理。
          java 代碼
          1.        public String getPassword(String userId){   
          2.        try{   
          3.        ……   
          4.               Statement s = con.createStatement();   
          5.               ……   
          6.        Catch(SQLException sqlEx){   
          7.               ……   
          8.    }   
          9. ……   
          10. }   
          或者
          java 代碼
          1. public String getPassword(String userId)throws SQLException{   
          2.    Statement s = con.createStatement();   
          3. }  
          (當然,像Connection,Satement這些資源是需要及時關閉的,這里僅是為了說明checked 異常必須強制調用者進行捕獲或繼續拋出)
           
          unChecked異常也稱為運行時異常,通常 RuntimeException都表示用戶無法恢復的異常,如無法獲得數據庫連接,不能打開文件等。雖然用戶也可以像處理checked異常一樣捕獲 unChecked異常。但是如果調用者并沒有去捕獲unChecked異常時,編譯器并不會強制你那么做。
           
          比如一個把字符轉換為整型數值的代碼如下:
           
          java 代碼
          1. String str = “123”;   
          2. int value = Integer.parseInt(str);  
           
          parseInt的方法簽名為:
          java 代碼
          1. public static int parseInt(String s) throws NumberFormatException  
           
          當傳入的參數不能轉換成相應的整數時,將會拋出NumberFormatException。因為NumberFormatException擴展于RuntimeException,是unChecked異常。所以調用parseInt方法時無需要try…catch
           
          因為java不強制調用者對unChecked異常進行捕獲或往上拋 出。所以程序員總是喜歡拋出unChecked異常。或者當需要一個新的異常類時,總是習慣的從RuntimeException擴展。當你去調用它些方 法時,如果沒有相應的catch塊,編譯器也總是讓你通過,同時你也根本無需要去了解這個方法倒底會拋出什么異常。看起來這似乎倒是一個很好的辦法,但是 這樣做卻是遠離了java異常處理的真實意圖。并且對調用你這個類的程序員帶來誤導,因為調用者根本不知道需要在什么情況下處理異常。而checked異 常可以明確的告訴調用者,調用這個類需要處理什么異常。如果調用者不去處理,編譯器都會提示并且是無法編譯通過的。當然怎么處理是由調用者自己去決定的。
           
                 所以Java推薦人們在應用代碼中應該使用checked異常。就像我們在上節提到運用異常的好外在于可以強制調用者必須對將會產生的異常進行處理。包括在《java Tutorial》等java官方文檔中都把checked異常作為標準用法。
                 使用checked異常,應意味著有許多的try…catch在你的代碼中。當在編寫和處理越來越多的try…catch塊之后,許多人終于開始懷疑checked異常倒底是否應該作為標準用法了。
          甚至連大名鼎鼎的《thinking in java》的作者Bruce Eckel也改變了他曾經的想法。Bruce Eckel甚至主張把unChecked異常作為標準用法。并發表文章,以試驗checked異常是否應該從java中去掉。Bruce Eckel語:“當少量代碼時,checked異常無疑是十分優雅的構思,并有助于避免了許多潛在的錯誤。但是經驗表明,對大量代碼來說結果正好相反”
          關于checked異常和unChecked異常的詳細討論可以參考
           
          使用checked異常會帶來許多的問題。
                 checked異常導致了太多的try…catch 代碼
                        可能有很多checked異常對開發人員來說是無法合理地進行處理的,比如 SQLException。而開發人員卻不得不去進行try…catch。當開發人員對一個checked異常無法正確的處理時,通常是簡單的把異常打印 出來或者是干脆什么也不干。特別是對于新手來說,過多的checked異常讓他感到無所適從。
          java 代碼
          1.        try{   
          2.        ……   
          3.               Statement s = con.createStatement();   
          4.               ……   
          5.        Catch(SQLException sqlEx){   
          6.               sqlEx.PrintStackTrace();   
          7.    }   
          8.    或者   
          9.        try{   
          10.        ……   
          11.               Statement s = con.createStatement();   
          12.               ……   
          13.        Catch(SQLException sqlEx){   
          14.           //什么也不干   
          15. }   
           
          checked異常導致了許多難以理解的代碼產生
                  當開發人員必須去捕獲一個自己無法正確處理的checked異常,通常的是重新封裝成一個新的異常后再拋出。這樣做并沒有為程序帶來任何好處。反而使代碼晚難以理解。
          就像我們使用JDBC代碼那樣,需要處理非常多的try…catch.,真正有用的代碼被包含在try…catch之內。使得理解這個方法變理困難起來
          checked異常導致異常被不斷的封裝成另一個類異常后再拋出
          java 代碼
          1.         public void methodA()throws ExceptionA{   
          2.          …..          
          3.           throw new ExceptionA();        
          4. }   
          5.           
          6. public void methodB()throws ExceptionB{   
          7.    try{   
          8.       methodA();   
          9.       ……   
          10.    }catch(ExceptionA ex){   
          11.    throw new ExceptionB(ex);   
          12.    }   
          13. }   
          14.            
          15.         Public void methodC()throws ExceptinC{   
          16.        try{   
          17.          methodB();   
          18.          …   
          19.        }   
          20.        catch(ExceptionB ex){   
          21.           throw new ExceptionC(ex);   
          22.         }   
          23.     }   
          我們看到異常就這樣一層層無休止的被封裝和重新拋出。
           
          checked異常導致破壞接口方法
             一個接口上的一個方法已被多個類使用,當為這個方法額外添加一個checked異常時,那么所有調用此方法的代碼都需要修改。
           
          可見上面這些問題都是因為調用者無法正確的處理checked異常時而被迫去捕獲和處理,被迫封裝后再重新拋出。這樣十分不方便,并不能帶來任何好處。在這種情況下通常使用unChecked異常。
          chekced異常并不是無一是處,checked異常比傳統編程的錯誤返回值要好用得多。通過編譯器來確保正確的處理異常比通過返回值判斷要好得多。
          如果一個異常是致命的,不可恢復的。或者調用者去捕獲它沒有任何益處,使用unChecked異常。
          如果一個異常是可以恢復的,可以被調用者正確處理的,使用checked異常
          在使用unChecked異常時,必須在在方法聲明中詳細的說明該方法可能會拋出的unChekced異常。由調用者自己去決定是否捕獲unChecked異常
           
          倒底什么時候使用checked異常,什么時候使用unChecked異常?并沒有一個絕對的標準。但是筆者可以給出一些建議
          當所有調用者必須處理這個異常,可以讓調用者進行重試操作;或者該異常相當于該方法的第二個返回值。使用checked異常。
          這個異常僅是少數比較高級的調用者才能處理,一般的調用者不能正確的處理。使用unchecked異常。有能力處理的調用者可以進行高級處理,一般調用者干脆就不處理。
          這個異常是一個非常嚴重的錯誤,如數據庫連接錯誤,文件無法打開等。或者這些異常是與外部環境相關的。不是重試可以解決的。使用unchecked異常。因為這種異常一旦出現,調用者根本無法處理。
          如果不能確定時,使用unchecked異常。并詳細描述可能會拋出的異常,以讓調用者決定是否進行處理。
           
          3. 設計一個新的異常類
          在設計一個新的異常類時,首先看看是否真正的需要這個異常類。一般情況下盡量不要去設計新的異常類,而是盡量使用java中已經存在的異常類。
          java 代碼
          1. IllegalArgumentException, UnsupportedOperationException  
           
          不管是新的異常是chekced異常還是unChecked異常。我們都必須考慮異常的嵌套問題。
          java 代碼
          1. public void methodA()throws ExceptionA{   
          2.          …..          
          3.           throw new ExceptionA();        
          4. }   
           
          方法methodA聲明會拋出ExceptionA.
           
          public void methodB()throws ExceptionB
          methodB聲明會拋出ExceptionB,當在methodB方 法中調用methodA時,ExceptionA是無法處理的,所以ExceptionA應該繼續往上拋出。一個辦法是把methodB聲明會拋出 ExceptionA.但這樣已經改變了MethodB的方法簽名。一旦改變,則所有調用methodB的方法都要進行改變。
          另一個辦法是把ExceptionA封裝成ExceptionB,然后再拋出。如果我們不把ExceptionA封裝在ExceptionB中,就丟失了根異常信息,使得無法跟蹤異常的原始出處。
          java 代碼
          1. public void methodB()throws ExceptionB{   
          2.    try{   
          3.       methodA();   
          4.       ……   
          5.    }catch(ExceptionA ex){   
          6.      throw new ExceptionB(ex);   
          7.    }   
          8. }  
           
             如上面的代碼中,ExceptionB嵌套一個ExceptionA.我們暫且把ExceptionA稱為“起因異常”,因為ExceptionA導致了ExceptionB的產生。這樣才不使異常信息丟失。
          所以我們在定義一個新的異常類時,必須提供這樣一個可以包含嵌套異常的構造函數。并有一個私有成員來保存這個“起因異常”。
          java 代碼
          1. public Class ExceptionB extends Exception{   
          2. private Throwable cause;   
          3.     
          4. public ExceptionB(String msg, Throwable ex){   
          5.  super(msg);   
          6.  this.cause = ex;   
          7. }   
          8.     
          9. public ExceptionB(String msg){   
          10.  super(msg);   
          11. }   
          12.     
          13. public ExceptionB(Throwable ex){   
          14.  this.cause = ex;   
          15. }   
          16. }   
          當然,我們在調用printStackTrace方法時,需要把所有的“起因異常”的信息也同時打印出來。所以我們需要覆寫printStackTrace方法來顯示全部的異常棧跟蹤。包括嵌套異常的棧跟蹤。
          java 代碼
          1. public void printStackTrace(PrintStrean ps){   
          2. if(cause == null){   
          3.  super.printStackTrace(ps);   
          4. }else{   
          5.  ps.println(this);   
          6.  cause.printStackTrace(ps);   
          7. }   
          8. }   
           
          一個完整的支持嵌套的checked異常類源碼如下。我們在這里暫且把它叫做NestedException
           
          java 代碼
          1. public NestedException extends Exception{   
          2. private Throwable cause;   
          3. public NestedException (String msg){   
          4.  super(msg);   
          5. }   
          6.     
          7. public NestedException(String msg, Throwable ex){   
          8.  super(msg);   
          9.  This.cause = ex;   
          10. }   
          11.     
          12. public Throwable getCause(){   
          13.  return (this.cause == null ? this :this.cause);   
          14. }   
          15.     
          16. public getMessage(){   
          17.  String message = super.getMessage();   
          18.  Throwable cause = getCause();   
          19.    if(cause != null){   
          20.      message = message + “;nested Exception is ” + cause;   
          21.    }   
          22.  return message;   
          23. }   
          24. public void printStackTrace(PrintStream ps){   
          25.  if(getCause == null){   
          26.     super.printStackTrace(ps);   
          27.        
          28.  }else{   
          29.  ps.println(this);   
          30.  getCause().printStackTrace(ps);   
          31.  }   
          32. }   
          33.     
          34. public void printStackTrace(PrintWrite pw){   
          35.  if(getCause() == null){   
          36.     super.printStackTrace(pw);   
          37.  }   
          38.  else{   
          39.     pw.println(this);   
          40.     getCause().printStackTrace(pw);   
          41.  }   
          42. }   
          43. public void printStackTrace(){   
          44.  printStackTrace(System.error);   
          45. }   
          46. }   
          47.     
          同樣要設計一個unChecked異常類也與上面一樣。只是需要繼承RuntimeException。
           
           
          4. 如何記錄異常
          作為一個大型的應用系統都需要用日志文件來記錄系統的運行,以便于跟蹤和記錄系統的運行情況。系統發生的異常理所當然的需要記錄在日志系統中。
          java 代碼
          1. public String getPassword(String userId)throws NoSuchUserException{   
          2. UserInfo user = userDao.queryUserById(userId);   
          3. If(user == null){   
          4.  Logger.info(“找不到該用戶信息,userId=”+userId);   
          5.  throw new NoSuchUserException(“找不到該用戶信息,userId=”+userId);   
          6. }   
          7. else{   
          8.  return user.getPassword();   
          9. }   
          10. }   
          11.     
          12. public void sendUserPassword(String userId)throws Exception {   
          13. UserInfo user = null;   
          14. try{   
          15.   user = getPassword(userId);   
          16.    //……..   
          17.  sendMail();   
          18.  //   
          19. }catch(NoSuchUserException ex)(   
          20.    logger.error(“找不到該用戶信息:”+userId+ex);   
          21.    throw new Exception(ex);   
          22. }   
           
          我們注意到,一個錯誤被記錄了兩次.在錯誤的起源位置我們僅是以info級別進行記錄。而在sendUserPassword方法中,我們還把整個異常信息都記錄了。
          筆者曾看到很多項目是這樣記錄異常的,不管三七二一,只有遇到異常就把整個異常全部記錄下。如果一個異常被不斷的封裝拋出多次,那么就被記錄了多次。那么異常倒底該在什么地方被記錄?
          異常應該在最初產生的位置記錄
           
          如果必須捕獲一個無法正確處理的異常,僅僅是把它封裝成另外一種異常往上拋出。不必再次把已經被記錄過的異常再次記錄。
           
          如果捕獲到一個異常,但是這個異常是可以處理的。則無需要記錄異常
           
          java 代碼
          1. public Date getDate(String str){   
          2.  Date applyDate = null;   
          3. SimpleDateFormat format = new SimpleDateFormat(“MM/dd/yyyy”);   
          4. try{   
          5.  applyDate = format.parse(applyDateStr);   
          6. }   
          7. catch(ParseException ex){   
          8.  //乎略,當格式錯誤時,返回null   
          9. }   
          10. return applyDate;   
          11. }   
           
          捕獲到一個未記錄過的異常或外部系統異常時,應該記錄異常的詳細信息
          java 代碼
          1. try{   
          2.        ……   
          3.         String sql=”select * from userinfo”;   
          4.               Statement s = con.createStatement();   
          5.               ……   
          6.        Catch(SQLException sqlEx){   
          7.           Logger.error(“sql執行錯誤”+sql+sqlEx);   
          8. }   
                
             究竟在哪里記錄異常信息,及怎么記錄異常信息,可能是見仁見智的問題了。甚至有些系統讓異常類一記錄異常。當產生一個新異常對象時,異常信息就被自動記錄。
          java 代碼
          1.   public class BusinessException extends Exception {   
          2.       private void logTrace() {   
          3.           StringBuffer buffer=new StringBuffer();   
          4.           buffer.append("Business Error in Class: ");   
          5.           buffer.append(getClassName());   
          6.           buffer.append(",method: ");   
          7.           buffer.append(getMethodName());   
          8.           buffer.append(",messsage: ");   
          9.           buffer.append(this.getMessage());   
          10.           logger.error(buffer.toString());   
          11.              
          12. }   
          13. public BusinessException(String s) {   
          14.          super(s);   
          15. race();   
          16. }   
          這似乎看起來是十分美妙的,其實必然導致了異常被重復記錄。同時違反了“類的職責分配原則”,是一種不好的設計。記錄異常不屬于異常類的行為,記錄異常應 該由專門的日志系統去做。并且異常的記錄信息是不斷變化的。我們在記錄異常同應該給更豐富些的信息。以利于我們能夠根據異常信息找到問題的根源,以解決問 題。
          雖然我們對記錄異常討論了很多,過多的強調這些反而使開發人員更為疑惑,一種好的方式是為系統提供一個異常處理框架。由框架來決定是否記錄異常和怎么記錄異常。而不是由普通程序員去決定。但是了解些還是有益的。
          5. J2EE項目中的異常處理
          目前,J2ee項目一般都會從邏輯上分為多層。比較經典的分為三層:表示層,業務層,集成層(包括數據庫訪問和外部系統的訪問)。
          J2ee項目有著其復雜性,J2ee項目的異常處理需要特別注意幾個問題。
          在分布式應用時,我們會遇到許多checked異常。所有RMI調用 (包括EJB遠程接口調用)都會拋出java.rmi.RemoteException;同時RemoteException是checked異常,當我 們在業務系統中進行遠程調用時,我們都需要編寫大量的代碼來處理這些checked異常。而一旦發生RemoteException這些checked異 常對系統是非常嚴重的,幾乎沒有任何進行重試的可能。也就是說,當出現RemoteException這些可怕的checked異常,我們沒有任何重試的 必要性,卻必須要編寫大量的try…catch代碼去處理它。一般我們都是在最底層進行RMI調用,只要有一個RMI調用,所有上層的接口都會要求拋出 RemoteException異常。因為我們處理RemoteException的方式就是把它繼續往上拋。這樣一來就破壞了我們業務接口。 RemoteException這些J2EE系統級的異常嚴重的影響了我們的業務接口。我們對系統進行分層的目的就是減少系統之間的依賴,每一層的技術改 變不至于影響到其它層。
           
          java 代碼
          1. //   
          2. public class UserSoaImpl implements UserSoa{   
          3.    public UserInfo getUserInfo(String userId)throws RemoteException{   
          4.       //……   
          5. 遠程方法調用.   
          6.       //……   
          7.    }   
          8. }   
          9. public interface UserManager{   
          10.    public UserInfo getUserInfo(Stirng userId)throws RemoteException;   
          11. }   
           
          同樣JDBC訪問都會拋出SQLException的checked異常。
           
          為了避免系統級的checked異常對業務系統的深度侵入,我們可以為 業務方法定義一個業務系統自己的異常。針對像SQLException,RemoteException這些非常嚴重的異常,我們可以新定義一個 unChecked的異常,然后把SQLException,RemoteException封裝成unChecked異常后拋出。
          如果這個系統級的異常是要交由上一級調用者處理的,可以新定義一個checked的業務異常,然后把系統級的異常封存裝成業務級的異常后再拋出。
          一般地,我們需要定義一個unChecked異常,讓集成層接口的所有方法都聲明拋出這unChecked異常
          java 代碼
          1. public DataAccessException extends RuntimeException{   
          2.  ……   
          3. }   
          4. public interface UserDao{   
          5.  public String getPassword(String userId)throws DataAccessException;   
          6. }   
          7.     
          8. public class UserDaoImpl implements UserDAO{   
          9. public String getPassword(String userId)throws DataAccessException{   
          10.  String sql = “select password from userInfo where userId= ‘”+userId+”’”;   
          11. try{   
          12.     …   
          13.      //JDBC調用   
          14.      s.executeQuery(sql);   
          15.     …   
          16.    }catch(SQLException ex){   
          17.       throw new DataAccessException(“數據庫查詢失敗”+sql,ex);   
          18.    }   
          19. }   
          20. }   
           
          定義一個checked的業務異常,讓業務層的接口的所有方法都聲明拋出Checked異常.
           
          java 代碼
          1. public class BusinessException extends Exception{   
          2.  …..   
          3. }   
          4.     
          5. public interface UserManager{   
          6.    public Userinfo copyUserInfo(Userinfo user)throws BusinessException{   
          7.       Userinfo newUser = null;   
          8.       try{   
          9.         newUser = (Userinfo)user.clone();   
          10. }catch(CloneNotSupportedException ex){   
          11.  throw new BusinessException(“不支持clone方法:”+Userinfo.class.getName(),ex);   
          12. }   
          13.  }   
          14. }  
           
          J2ee表示層應該是一個很薄的層,主要的功能為:獲得頁面請求,把頁 面的參數組裝成POJO對象,調用相應的業務方法,然后進行頁面轉發,把相應的業務數據呈現給頁面。表示層需要注意一個問題,表示層需要對數據的合法性進 行校驗,比如某些錄入域不能為空,字符長度校驗等。
          J2ee從頁面所有傳給后臺的參數都是字符型的,如果要求輸入數值或日期類型的參數時,必須把字符值轉換為相應的數值或日期值。
          如果表示層代碼校驗參數不合法時,應該返回到原始頁面,讓用戶重新錄入數據,并提示相關的錯誤信息。
           
          通常把一個從頁面傳來的參數轉換為數值,我們可以看到這樣的代碼
          java 代碼
          1. ModeAndView handleRequest(HttpServletRequest request,HttpServletResponse response)throws Exception{   
          2.    String ageStr = request.getParameter(“age”);   
          3.    int age = Integer.parse(ageStr);   
          4.    …………   
          5.     
          6.  String birthDayStr = request.getParameter(“birthDay”);   
          7. SimpleDateFormat format = new SimpleDateFormat(“MM/dd/yyyy”);   
          8. Date birthDay = format.parse(birthDayStr);   
          9.     
          10. }   
           
          上面的代碼應該經常見到,但是當用戶從頁面錄入一個不能轉換為整型的字符或一個錯誤的日期值。
          Integer.parse()方法被拋出一個 NumberFormatException的unChecked異常。但是這個異常絕對不是一個致命的異常,一般當用戶在頁面的錄入域錄入的值不合法 時,我們應該提示用戶進行重新錄入。但是一旦拋出unchecked異常,就沒有重試的機會了。像這樣的代碼造成大量的異常信息顯示到頁面。使我們的系統 看起來非常的脆弱。
          同樣,SimpleDateFormat.parse()方法也會拋出ParseException的unChecked異常。
          這種情況我們都應該捕獲這些unChecked異常,并給提示用戶重新錄入。
          java 代碼
          1. ModeAndView handleRequest(HttpServletRequest request,HttpServletResponse response)throws Exception{   
          2.    String ageStr = request.getParameter(“age”);   
          3. String birthDayStr = request.getParameter(“birthDay”);   
          4.    int age = 0;   
          5.  Date birthDay = null;   
          6. try{   
          7. age=Integer.parse(ageStr);   
          8.    }catch(NumberFormatException ex){   
          9.      error.reject(“age”,”不是合法的整數值”);   
          10.    }   
          11.    …………   
          12.     
          13.  try{   
          14. SimpleDateFormat format = new SimpleDateFormat(“MM/dd/yyyy”);   
          15.  birthDay = format.parse(birthDayStr);   
          16. }catch(ParseException ex){   
          17.  error.reject(“birthDay”,”不是合法的日期,請錄入’MM/dd/yyy’格式的日期”);   
          18. }   
          19.     
          20. }  
          在表示層一定要弄清楚調用方法的是否會拋出unChecked異常,什么情況下會拋出這些異常,并作出正確的處理。
          在表示層調用系統的業務方法,一般情況下是無需要捕獲異常的。如果調用的業務方法拋出的異常相當于第二個返回值時,在這種情況下是需要捕獲
          posted @ 2011-06-27 16:02 思無 閱讀(403) | 評論 (0)編輯 收藏

          package hello;
          public interface Hello extends java.rmi.Remote{
              String sayHello() throws java.rmi.RemoteException;
          }

          package hello;
          import java.rmi.
          *;
          public class HelloClient {
              
          public static void main(String args[]){
                  System.setSecurityManager(new RMISecurityManager());
                  try{
                      Hello obj 
          = (Hello)Naming.lookup("HelloServer");
                      String message
          =obj.sayHello();
                      System.out.println(message);
                  }catch(Exception e){
                      e.printStackTrace();
                  }
              }
          }

          package hello;
          import java.rmi.
          *;
          import java.rmi.registry.LocateRegistry;
          import java.rmi.server.UnicastRemoteObject;
          public class HelloImpl extends UnicastRemoteObject implements Hello{
              private String name;
              
          public HelloImpl(String s) throws java.rmi.RemoteException{
                  super();
                  name
          =s;
              }
              
          public String sayHello()throws RemoteException{
                  
          return "hello world";
              }
              
          public static void main(String args[]){
                  System.setSecurityManager(new RMISecurityManager());
                  try{
                      HelloImpl obj 
          = new HelloImpl("HelloServer");
                      LocateRegistry.createRegistry(
          1099); 
                      Naming.rebind("HelloServer", obj);
                      System.out.println("HelloImpl created 
          and bound in the registry to the name HelloServer");
                  }catch(Exception e){
                      e.printStackTrace();
                  }
              }
          }

          安全策略文件
          grant {
              permission java.security.AllPermission;
              };

          運行腳本:
          Set CLASSPATH=%CLASSPATH%;c:\         沒有空格
          javac -d .. *.java                                  在hello目錄下
          rmic -d . hello.HelloImpl                           在hello的父目錄下
          java -Djava.security.policy=file:C:/java.policy hello.HelloImpl        注意安全策略文件
          java -Djava.security.policy=file:/C:/java.policy hello.HelloClient     注意安全策略文件

          相關資料:
          http://blog.csdn.net/coolriver/archive/2004/09/10/100702.aspx
          http://topic.csdn.net/t/20020310/12/566253.html
          http://topic.csdn.net/u/20070426/08/b852e323-08c6-4f80-b87a-937e24af237d.html

          posted @ 2011-06-13 15:18 思無 閱讀(294) | 評論 (0)編輯 收藏

          /**
           * 改類掩飾了如何通過java.bean的類去獲知bean中的屬性并調用相應的set get方法
           
          */
          import java.beans.*;
          import java.lang.reflect.Method;
          public class JavaBeanInvoke {
              
          public static void main(String args[])throws Exception{
                  test1();
              }
              
              
          public static void test1()throws Exception{
                  Person person 
          = Person.class.newInstance();
                  
                  BeanInfo beaninfo 
          = Introspector.getBeanInfo(Person.class);
                  PropertyDescriptor[] porpertydescriptors 
          = beaninfo.getPropertyDescriptors();
                  
          for(PropertyDescriptor pd:porpertydescriptors){
                      System.out.println(pd.getName());
                      
          if(pd.getName().endsWith("name")){
                          Method setMethod
          =pd.getWriteMethod();
                          Method getMethod
          =pd.getReadMethod();
                          setMethod.invoke(person,
          "ShenZiping");
                          System.out.println(getMethod.invoke(person));
                          
          break;
                      }
                  }
              }
              
              
          public static void test2() throws Exception{
                  Person person 
          = Person.class.newInstance();
                  PropertyDescriptor pd 
          = new PropertyDescriptor("age",Person.class);
                  Method setMethod 
          = pd.getWriteMethod();
                  Method getMethod 
          = pd.getReadMethod();
                  setMethod.invoke(person, 
          56);
                  System.out.println(getMethod.invoke(person));
              }
          }

          /**
           * 代碼舉例了beanUtil包的普遍用法,需要apache的logging包和beanUtils包
           
          */
          import java.text.ParseException;
          import java.text.SimpleDateFormat;
          import java.util.Date;
          import java.util.HashMap;
          import java.util.Map;

          import org.apache.commons.beanutils.*;
          public class BeanUtilsInvoke {
              
          public static void main(String args[])throws Exception{
                  test1();
                  test2();
                  test3();
                  test4();
                  myConvertTest();
              }
              
          public static void test1()throws Exception{
                  Person person 
          = new Person();
                  BeanUtils.copyProperty(person, 
          "name""ShenZiping");
                  System.out.println(
          "test1"+person.getName());
              }
              
          public static void test2() throws Exception{
                  Person person 
          = new Person();
                  Map
          <String, String> map = new HashMap<String, String>();
                  map.put(
          "name""ShenZiping");
                  map.put(
          "age""65");
                  BeanUtils.populate(person, map);
                  System.out.println(
          "test2"+person.getAge());
                  System.out.println(
          "test2"+person.getName());
              }
              
              
          public static void test3() throws Exception{
                  Person p1 
          = new Person();
                  Person p2 
          = new Person();
                  p1.setAge(
          98);
                  p1.setName(
          "ShenZiping");
                  BeanUtils.copyProperties(p2, p1);
                  System.out.println(
          "test3"+p2.getAge());
                  System.out.println(
          "test3"+p2.getName());
              }
              
              
          public static void test4() throws Exception{
                  Person person 
          = new Person();
                  Man man 
          = new Man();
                  person.setName(
          "ShenZiping");
                  BeanUtils.copyProperties(man, person);
                  System.out.println(
          "test4"+man.getName());
              }
              
              
          public static void myConvertTest(){
                  ConvertUtils.register(
          new Converter(){
                      
          public Object convert(Class clazz, Object value){
                          
          if(clazz==Date.class){
                              SimpleDateFormat dateFormat 
          = new SimpleDateFormat("yyyy-MM-dd");
                              
          try{
                                  
          return dateFormat.parse((String)value);
                              }
          catch(ParseException e){
                                  
          throw new RuntimeException("invalid format");
                              }
                          }
                          
          return null;
                      }
                  }, Date.
          class);
                  Date date 
          = (Date)ConvertUtils.convert("2010-01-15",Date.class);
                  System.out.println(
          "myConvertTest"+date);
              }
          }
          posted @ 2011-06-13 12:38 思無 閱讀(805) | 評論 (0)編輯 收藏

          做了這么多年前臺的東西,還是第一次捧起前臺相關的書來看。
          這次看得是Robert Hoekman的第二本書,總體感覺看下來,比較受用,重點講了下面幾個詞匯。
          簡單,清楚,預期,反饋。
          簡單:界面要足夠的簡單,不要多,更不要無必要的“多“,要把“多“的東西隱藏起來,多指不常用的,比較“高級“的功能。
          清楚:突出什么要清楚,突出什么可以通過顏色,視覺習慣等方法。
          預期:用戶要知道自己操作的進度,比如填寫多頁表單。
          反饋:讓用戶知道自己操作的結果的提示,操作完頁面需要做出反饋以提示用戶操作的結果。

          該書從設計用戶登陸開始,中間穿插了一些網站小模塊的設計,到最終用戶退出系統的設計。比較完整的用31個瞬間講述了一個用戶瀏覽網站的過程。

          給自己最大的提示,老生常談,站在使用者的角度,方便使用者的目的,并盡可能依靠使用者的“抱怨”,改進系統的設計,提高使用者的效率。
          posted @ 2011-06-09 13:30 思無 閱讀(427) | 評論 (0)編輯 收藏

          轉自    oracle.sql.CLOB clob =null;  
              stmt 
          = conn.createStatement();  
              rs 
          = stmt.executeQuery(sql);  
              
          if (rs.next()) {  
                  System.out.println(rs.getClob(
          column).getClass());  
                  clob 
          = (oracle.sql.CLOB) rs.getClob(column);  
                  out 
          = new BufferedWriter(clob.getCharacterOutputStream());  
                  
          in = new BufferedReader(new StringReader(data));  
              }
          這個代碼很奇怪,看試沒有一點問題,但是,項目跑起來后,代碼 
          clob = (oracle.sql.CLOB) rs.getClob(column); 
          都會拋出java.lang.ClassCastException: oracle.sql.CLOB異常(WEB容器使用的是TOMCAT5.5),先以為是類型轉換的問題, 
          System.out.println(rs.getClob(column).getClass()); 
          但打印出來的是oracle.sql.clob 
          后又以為是驅動的問題,把classes12.jar換成了ojdbc14.jar 
          可問題還沒有解決 

          解決的方法: 

          在網上狂找,終于找到一位高人寫的一篇高水平的文章(主要是把我的問題給解決了,哈) 

          是因為驅動包重復了,我理解為類重名,我使用的是tomcat數據源,哪么,$TOMCAT_HOME$\comm\lib目錄下需要oracle驅動包,是給tomcat創建jndi數據源時用的,而項目中也要有oracle驅動包,是給程序編譯用的,最后使用eclilpse的java build path進行外部引用,使用應用程序編譯通過,但也不會把ojdbc14.jar的驅動包引入到發布目錄,再試,果然解決了問題。

          posted @ 2011-06-07 13:38 思無 閱讀(524) | 評論 (0)編輯 收藏

          Selectors

          Selector Example Selects
          * $("*") All elements
          #id $("#lastname") The element with id=lastname
          .class $(".intro") All elements with class="intro"
          element $("p") All p elements
          .class.class $(".intro.demo") All elements with the classes "intro" and "demo"
               
          :first $("p:first") The first p element
          :last $("p:last") The last p element
          :even $("tr:even") All even tr elements
          :odd $("tr:odd") All odd tr elements
               
          :eq(index) $("ul li:eq(3)") The fourth element in a list (index starts at 0)
          :gt(no) $("ul li:gt(3)") List elements with an index greater than 3
          :lt(no) $("ul li:lt(3)") List elements with an index less than 3
          :not(selector) $("input:not(:empty)") All input elements that are not empty
               
          :header $(":header") All header elements h1, h2 ...
          :animated $(":animated") All animated elements
               
          :contains(text) $(":contains('W3Schools')") All elements which contains the text
          :empty $(":empty") All elements with no child (elements) nodes
          :hidden $("p:hidden") All hidden p elements
          :visible $("table:visible") All visible tables
               
          s1,s2,s3 $("th,td,.intro") All elements with matching selectors
               
          [attribute] $("[href]") All elements with a href attribute
          [attribute=value] $("[href='default.htm']") All elements with a href attribute value equal to "default.htm"
          [attribute!=value] $("[href!='default.htm']") All elements with a href attribute value not equal to "default.htm"
          [attribute$=value] $("[href$='.jpg']") All elements with a href attribute value ending with ".jpg"
               
          :input $(":input") All input elements
          :text $(":text") All input elements with type="text"
          :password $(":password") All input elements with type="password"
          :radio $(":radio") All input elements with type="radio"
          :checkbox $(":checkbox") All input elements with type="checkbox"
          :submit $(":submit") All input elements with type="submit"
          :reset $(":reset") All input elements with type="reset"
          :button $(":button") All input elements with type="button"
          :image $(":image") All input elements with type="image"
          :file $(":file") All input elements with type="file"
               
          :enabled $(":enabled") All enabled input elements
          :disabled $(":disabled") All disabled input elements
          :selected $(":selected") All selected input elements
          :checked $(":checked") All checked input elements


          Events

          Method Description
          bind() Add one or more event handlers to matching elements
          blur() Triggers, or binds a function to the blur event of selected elements
          change() Triggers, or binds a function to the change event of selected elements
          click() Triggers, or binds a function to the click event of selected elements
          dblclick() Triggers, or binds a function to the dblclick event of selected elements
          delegate() Add one or more event handlers to current, or future, specified child elements of the matching elements
          die() Remove all event handlers added with the live() function
          error() Triggers, or binds a function to the error event of selected elements
          event.currentTarget The current DOM element within the event bubbling phase
          event.data Contains the optional data passed to jQuery.fn.bind when the current executing handler was bound
          event.isDefaultPrevented() Returns whether event.preventDefault() was called for the event object
          event.isImmediatePropagationStopped() Returns whether event.stopImmediatePropagation() was called for the event object
          event.isPropagationStopped() Returns whether event.stopPropagation() was called for the event object
          event.pageX The mouse position relative to the left edge of the document
          event.pageY The mouse position relative to the top edge of the document
          event.preventDefault() Prevents the default action of the event
          event.relatedTarget The other DOM element involved in the event, if any
          event.result This attribute contains the last value returned by an event handler that was triggered by this event, unless the value was undefined
          event.stopImmediatePropagation() Prevents other event handlers from being called
          event.stopPropagation() Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event
          event.target The DOM element that initiated the event
          event.timeStamp This attribute returns the number of milliseconds since January 1, 1970, when the event is triggered
          event.type Describes the nature of the event
          event.which Which key or button was pressed for a key or button event
          focus() Triggers, or binds a function to the focus event of selected elements
          focusin() Binds a function to the focusin event of selected elements
          focusout() Binds a function to the focusout event of selected elements
          hover() Binds one or two functions to the hover event of selected elements
          keydown() Triggers, or binds a function to the keydown event of selected elements
          keypress() Triggers, or binds a function to the keypress event of selected elements
          keyup() Triggers, or binds a function to the keyup event of selected elements
          live() Add one or more event handlers to current, or future, matching elements
          load() Triggers, or binds a function to the load event of selected elements
          mousedown() Triggers, or binds a function to the mouse down event of selected elements
          mouseenter() Triggers, or binds a function to the mouse enter event of selected elements
          mouseleave() Triggers, or binds a function to the mouse leave event of selected elements
          mousemove() Triggers, or binds a function to the mouse move event of selected elements
          mouseout() Triggers, or binds a function to the mouse out event of selected elements
          mouseover() Triggers, or binds a function to the mouse over event of selected elements
          mouseup() Triggers, or binds a function to the mouse up event of selected elements
          one() Add one or more event handlers to matching elements. This handler can only be triggered once per element
          ready() Binds a function to the ready event of a document
          (when an HTML document is ready to use)
          resize() Triggers, or binds a function to the resize event of selected elements
          scroll() Triggers, or binds a function to the scroll event of selected elements
          select() Triggers, or binds a function to the select event of selected elements
          submit() Triggers, or binds a function to the submit event of selected elements
          toggle() Binds two or more functions to the toggle between for the click event for selected elements
          trigger() Triggers all events bound to the selected elements
          triggerHandler() Triggers all functions bound to a specified event for the selected elements
          unbind() Remove an added event handler from selected elements
          undelegate() Remove an event handler to selected elements, now or in the future
          unload() Triggers, or binds a function to the unload event of selected elements

          Effect
          Method Description
          animate() Performs a custom animation (of a set of CSS properties) for selected elements
          clearQueue() Removes all queued functions for the selected element
          delay() Sets a delay for all queued functions for the selected element
          dequeue() Runs the next queued functions for the selected element
          fadeIn() Gradually changes the opacity, for selected elements, from hidden to visible
          fadeOut() Gradually changes the opacity, for selected elements, from visible to hidden
          fadeTo() Gradually changes the opacity, for selected elements, to a specified opacity
          hide() Hides selected elements
          queue() Shows the queued functions for the selected element
          show() Shows hidden selected elements
          slideDown() Gradually changes the height, for selected elements, from hidden to visible
          slideToggle() Toggles between slideUp() and slideDown() for selected elements
          slideUp() Gradually changes the height, for selected elements, from visible to hidden
          stop() Stops a running animation on selected elements
          toggle() Toggles between hide() and show(), or custom functions, for selected elements

          HTML

          Method Description
          addClass() Adds one or more classes (for CSS) to selected elements
          after() Inserts content after selected elements
          append() Inserts content at the end of (but still inside) selected elements
          appendTo() Inserts content at the end of (but still inside) selected elements
          attr() Sets or returns an attribute and value of selected elements
          before() Inserts content before selected elements
          clone() Makes a copy of selected elements
          detach() Removes (but keeps a copy of) selected elements
          empty() Removes all child elements and content from selected elements
          hasClass() Checks if any of the selected elements have a specified class (for CSS)
          html() Sets or returns the content of selected elements
          insertAfter() Inserts HTML markup or elements after selected elements
          insertBefore() Inserts HTML markup or elements before selected elements
          prepend() Inserts content at the beginning of (but still inside) selected elements
          prependTo() Inserts content at the beginning of (but still inside) selected elements
          remove() Removes selected elements
          removeAttr() Removes an attribute from selected elements
          removeClass() Removes one or more classes (for CSS) from selected elements
          replaceAll() Replaces selected elements with new content
          replaceWith() Replaces selected elements with new content
          text() Sets or returns the text content of selected elements
          toggleClass() Toggles between adding/removing one or more classes (for CSS) from selected elements
          unwrap() Removes the parent element of the selected elements
          val() Sets or returns the value attribute of the selected elements (form elements)
          wrap() Wraps specified HTML element(s) around each selected element
          wrapAll() Wraps specified HTML element(s) around all selected elements
          wrapInner() Wraps specified HTML element(s) around the content of each selected element

          CSS

          Method Description
          addClass() Adds one or more classes to selected elements
          css() Sets or returns one or more style properties for selected elements
          hasClass() Checks if any of the selected elements have a specified class
          height() Sets or returns the height of selected elements
          offset() Sets or returns the position (relative to the document) for selected elements
          offsetParent() Returns the first parent element that is positioned
          position() Returns the position (relative to the parent element) of the first selected element
          removeClass() Removes one or more classes from selected elements
          scrollLeft() Sets or returns the horizontal position of the scrollbar for the selected elements
          scrollTop() Sets or returns the vertical position of the scrollbar for the selected elements
          toggleClass() Toggles between adding/removing one or more classes from selected elements
          width() Sets or returns the width of selected elements

          AJAX

          Method Description
          $.ajax() Performs an AJAX request
          ajaxComplete() Specifies a function to run when the AJAX request completes
          ajaxError() Specifies a function to run when the AJAX request completes with an error
          ajaxSend() Specifies a function to run before the AJAX request is sent
          $.ajaxSetup() Sets the default values for future AJAX requests
          ajaxStart() Specifies a function to run when the first AJAX request begins
          ajaxStop() Specifies a function to run when all AJAX requests have completed
          ajaxSuccess() Specifies a function to run an AJAX request completes successfully
          $.get() Loads data from a server using an AJAX HTTP GET request
          $.getJSON() Loads JSON-encoded data from a server using a HTTP GET request
          $.getScript() Loads (and executes) a JavaScript from the a server using an AJAX HTTP GET request
          load() Loads data from a server and puts the returned HTML into the selected element
          $.param() Creates a serialized representation of an array or object (can be used as URL query string for AJAX requests)
          $.post() Loads data from a server using an AJAX HTTP POST request
          serialize() Encodes a set of form elements as a string for submission
          serializeArray() Encodes a set of form elements as an array of names and values

          MISC

          Method Description
          data() Attaches data to, or gets data from, selected elements
          each() Run a function for each element matched by the jQuery selector
          get() Get the DOM elements matched by the selector
          index() Search for a given element from among the matched elements
          $.noConflict() Release jQuery's control of the $ variable
          $.param() Creates a serialized representation of an array or object (can be used as URL query string for AJAX requests)
          removeData() Removes a previously-stored piece of data
          size() Return the number of DOM elements matched by the jQuery selector
          toArray() Retrieve all the DOM elements contained in the jQuery set, as an array
          posted @ 2011-05-31 16:19 思無 閱讀(374) | 評論 (0)編輯 收藏

           
          //被觀察者接口,有添加觀察者對象,喚醒所有觀察者等方法申明。
          public
           interface ISubject {
              
          public void setName(String name);
              
          public String getName();
              
          public void addObserver(IObserver o);
              
          public void notifyAllObserver();
          }

          import java.util.*;
          public class Subject implements ISubject{
              
          private String name;
              List
          <IObserver> observers = new ArrayList<IObserver>();
              
          public Subject(){}
              
              
          public Subject(String name){
                  
          this.name=name;
              }
              
          public String getName(){
                  
          return this.name;
              }
              
          public void setName(String name){
                  
          this.name=name;
              }
              
          public void addObserver(IObserver o){
                  observers.add(o);
              }
              
          public void notifyAllObserver(){
                  
          for(int i=0;i<observers.size();i++){
                      observers.get(i).showInfo();
                  }
              }
          }

          //觀察者接口。
          public interface IObserver {
              
          public void showInfo();
          }

          public class Observer implements IObserver{
              
              
          private ISubject sjtref = null;
              
              
          public void setRef(ISubject sjt){
                  
          this.sjtref=sjt;
              }
              
          public Observer(ISubject sjtref){
                  
          super();
                  
          this.sjtref=sjtref;
              }
              
          public void showInfo(){
                  System.out.println(
          "Observering:"+sjtref.getName());
              }
          }

          public class ObserverMain {
              
          public static void main(String args[]){
                  //新建被觀察對象
                  ISubject subject = new Subject("Shen,Ziping");
                  //新建觀察者對象
                  IObserver observer1 = new Observer(subject);
                  //注冊
                  subject.addObserver(observer1);
                  //喚醒觀察者
                  subject.notifyAllObserver();
              }
          }
          posted @ 2011-05-30 12:24 思無 閱讀(214) | 評論 (0)編輯 收藏


          public
           interface IMobilePhone {
              
          public void call();
          }

          public class NokiaMPhone implements IMobilePhone{
              
          public void call(){
              }
          }

          public class OppoMPhone implements IMobilePhone{
              
          public void call(){
              }
          }

          public interface IFactory {
              
          public IMobilePhone createNokiaPhone();
              
          public IMobilePhone createOppoPhone();
          }

          public class MobilePhoneFactory implements IFactory{
              
          public IMobilePhone createNokiaPhone(){
                  
          return new NokiaMPhone();
              }
              
          public IMobilePhone createOppoPhone(){
                  
          return new OppoMPhone();
              }
          }

          public class Client {
              
          public static void main(String args[]){
                  IFactory factory 
          = new MobilePhoneFactory();
                  IMobilePhone nokia 
          = factory.createNokiaPhone();
                  IMobilePhone oppo 
          = factory.createOppoPhone();
                  nokia.call();
                  oppo.call();
              }
          }

          就代碼上而言,工廠模式和抽象工廠模式功能上是差不多的。都通過借口遍程實現了比較好的代碼隔離。不同的地方在于factory類的組織。工廠模式對每一個產品均實現一個工廠。而抽象工廠在一個工廠類中建立多個方法返回多種產品。
          posted @ 2011-05-27 14:21 思無 閱讀(253) | 評論 (0)編輯 收藏

          僅列出標題
          共3頁: 上一頁 1 2 3 下一頁 
          主站蜘蛛池模板: 新野县| 夏邑县| 宜良县| 高平市| 长寿区| 松溪县| 宁都县| 乌苏市| 孟村| 海阳市| 蓬莱市| 衡南县| 武宣县| 乌苏市| 绥德县| 娄烦县| 安平县| 股票| 咸阳市| 兴仁县| 万载县| 洞头县| 顺平县| 囊谦县| 美姑县| 万安县| 博客| 徐闻县| 二连浩特市| 开阳县| 江西省| 兴文县| 鄂伦春自治旗| 彭泽县| 凤山县| 清原| 禄劝| 军事| 太谷县| 嘉定区| 通化县|