Java Tools

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            83 隨筆 :: 0 文章 :: 16 評論 :: 0 Trackbacks

          #

          作者:Chris Schalk

          AJAX 核心基礎技術的真實概述。

          2006 年 4 月發布

          迄今為止,您可能已經聽過太多有關 AJAX 的宣傳報道,而且很多產品都宣稱它們支持或“兼容”AJAX。但是,很多人可能一直無法從技術角度對 AJAX 的實質進行簡單、嚴謹的闡釋。本文將擯棄所有華麗詞藻,從平實的角度對構成 AJAX 的核心基礎進行概述。

           

          首先,AJAX 是個新事物嗎?

          并非如此。遠程 Javascript 在最近掀起了一輪熱潮。利用它,開發人員能夠使用 XML 數據與服務器交互。而 AJAX 就是一種遠程 Javascript。AJAX 之所以成為可能,是因為現在許多主要的瀏覽器都提供可進行獨立 XML HTTP 請求的對象。Internet Explorer 5 以及更高版本提供了一個 XMLHTTP 對象,而基于 Mozilla 的瀏覽器則提供了一個 XMLHttpRequest 對象。這些對象都能夠從服務器請求 XML 數據,并以類似的方式處理這些數據。所有能夠動態提供 XML 的技術都可以使用服務器端 AJAX 組件。任何動態 Web 技術(從 PHP 到 Servlet)都可以充當 AJAX 服務器。

           

          遠程 Javascript 與 AJAX 的缺點之一是,頁面作者(設計最終頁面的人員)必須編寫相當數量的 Javascript 代碼來管理 XMLHTTP 交互。幸好,JavaServer Faces (JSF) 為此提供了一個解決方案,從而使 AJAX 更加易于使用。

          Ajax Under The Hood

          只有了解了 AJAX 客戶端-服務器事務中涉及的核心 AJAX 體系結構后,方可進一步理解與其他技術(如 JSF)集成的更為高級的 AJAX 示例。

          AJAX 目前可以提供以下兩種核心技術:

          • 支持 Javascript 和支持 XMLHTTP 和 XMLHttpRequest 對象的瀏覽器
          • 能夠以 XML 響應的 HTTP 服務器技術

          因為所有流行的瀏覽器都支持 Javascript 和必要的 XMLHTTP 請求對象,且幾乎所有 Web 服務器技術均可生成 XML(或任何標記),所以核心 AJAX 技術普遍適用。

          最簡單的 AJAX 應用程序實質上就是一個帶有 Javascript 函數的標準 HTML 用戶界面,該界面可與能動態生成 XML 的 HTTP 服務器進行交互。任何動態 Web 技術(從 CGI 到 Servlet,以及本文稍后將談到的 JSF)都可充當服務器端 AJAX 技術。

          核心 AJAX 應用程序的主要組件包括:

          • HTML 頁面,其中包含:
            • 與 AJAX Javascript 函數交互的 UI 元素
            • 與 AJAX 服務器交互的 Javascript 函數
          • 可處理 HTTP 請求并以 XML 標記響應的服務器端 Web 技術。

          這些元素如圖 1 所示。

          圖 1

          圖 1 核心 AJAX 體系結構

          了解了關鍵元素后,我們就可以設計一個包含輸入域、按鈕或任何可鏈接至 Javascript 的元素的 HTML 用戶界面了。例如,按下按鈕可激活某個 Javascript 函數,或者更深入些,在用戶向輸入域鍵入內容時可激活某個 Javascript 函數。為此,您可以將 onkeyup= 賦予 Javascript 函數的值來處理輸入域中的數據。例如,當發生 onkeyup 事件(即鍵入內容)時,輸入域“searchField”將調用 Javascript 函數 lookup( )。

          <input type="text" id="searchField"
          size="20" onkeyup="lookup('searchField');">
          

          除了響應用戶界面交互(例如鍵入)外,AJAX Javascript 函數還可根據自己的計時器進行獨立操作。(可以使用該方法執行 AJAX autosave(自動保存)特性。)

          如何發出 XML HTTP 請求

          現在,我們來了解如何調用 AJAX Javascript 代碼。請看以下 Javascript 代碼,該代碼可發出一個 XML HTTP 請求:

          if (window.XMLHttpRequest) {
          req = new XMLHttpRequest();
          }
          else if (window.ActiveXObject) {
          req = new
          ActiveXObject("Microsoft.XMLHTTP");
          }   

          利用該代碼斷,主要的瀏覽器(Internet Explorer 和 Mozilla/Safari)都可向服務器發出獨立的 HTTP 請求。該代碼首先檢查瀏覽器是否支持上文提及的兩個支持的 XMLHTTP 對象,然后對其中之一進行實例化。

          一旦對 XMLHttpRequest(或 Microsoft 的 XMLHTTP)進行了實例化,即可以通過完全相同的方式對其進行操作。

          要初始化到服務器的連接,需使用以下 open 方法:

          req.open("GET", url, true);
          

          第一個參數是 HTTP 方法(GET POST)。第二個參數是服務器(或使用 POST 的表單操作)的 URL;第三個參數為 true,則表明可進行異步調用(“A”代表 AJAX)。這意味著該瀏覽器可以在實現請求的同時繼續執行其他操作。open 方法中若為 false 值,則表明為非異步處理或順序處理。我們不建議如此,這是因為您的瀏覽器會在返回響應前停止操作。

          使用 open 初始化連接后,可進行 onreadystatechange 調用(只適用于異步調用)。這將注冊一個回調函數,一旦請求完成就會調用該函數:

          req.onreadystatechange = processXMLResponse;
          

          在完成請求后,將調用處理 XML 響應的 processXMLResponse( ) 函數。可以通過 onreadystatechange 語句以內聯方式聲明回調函數:

          req.onreadystatechange = processXMLResponse() {
          // process request
          };
          

          還可使用 req.setRequestHeader 指定任何標題內容,如:

          req.setRequestHeader("Cookie", "someKey=true");
          

          一旦完全初始化了 XMLHTTP 請求對象 (req),就可使用 send( ) 初始化對服務器的調用:

          req.send(null);
          

          對于 GET 請求,使用 null 值或空字符串“”。

          POST 請求包含一個帶有表單數據的字符串參數。它們也要求在請求的標題中設置 Content-Type。以下兩行演示了如何執行 AJAX POST 請求:

          req.setRequestHeader("Content-Type",
          "application/x-www-form-urlencoded";
          req.send("name=scott&email=stiger@foocorp.com");
          

          完成請求后調用的回調函數通常具有確保請求不會發生錯誤的代碼。這可通過檢查 readyState 以及 HTTP 請求的整體狀態來實現。(readystate 為 4 表示 XMLHTTP 請求完整,而 200 表示請求成功(404 含義正好相反)。

          function processXMLResponse() {
          if (req.readyState == 4) {
          if (request.status != 200) {
          // Process the XML response
          }
          }
          }
          

          XML 響應的處理是通過使用標準 Javascript DOM 方法完成的。例如,要從輸入的 XML 流中抽取員工姓名:

          <employee>
          Chris
          </employee>
          

          您可以使用以下代碼:

          var name = req.responseXML.getElementsByTagName("employee")[0];
          

          分析更為復雜的 XML 會使用如下代碼迭代元素:

          for (i=0;i<elements.length;i++) {
          for (j=0;j<elements[i].childNodes.length;j++) {
          var ElementData = elements[i].childNodes[j].firstChild.nodeValue;
          }
          }
          

          結合使用 XMLHttpRequest 和 HTML

          請注意,通過 XMLHttpRequest 獲得 XML 響應無需總是格式良好和有效。因此,AJAX 服務器端組件可以直接將 HTML 內容發送至客戶端。然后,JavaScript 可使用 req.responseText 方法/屬性(它只是將內容作為字符串進行檢索)檢索該 HTML 內容。可以使用該 HTML 字符串文本以任何方式更改頁面。例如,對于以下 HTML 流:

          <h2>Hello there!</h2>
          <p> This is <b>HTML</b></p>

          可使用以下語句檢索至一個字符串中:

          var HTMLcontent = req.responseText;
          

          之后通過 id="div1" 添加至指定的 HTML DIV。

          document.getElementById("div1").innerHTML += HTMLcontent;
          

          JSF 如何支持 AJAX

          JSF 及其以組件為中心的體系結構通過允許 JSF 組件全權處理 Javascript 和嵌入式 AJAX“管件”解決了 AJAX 的固有難題。JSF 頁面作者甚至無需關注客戶端與服務器之間的 AJAX 交互。它們只需像使用其他 JSF 組件那樣使用支持 AJAX 的 JSF 組件即可,而且感覺更好。JSF 與 AJAX 的結合使用前途光明!

          保持關注!

          posted @ 2007-07-02 19:55 和田雨 閱讀(270) | 評論 (0)編輯 收藏

          Java SE 6中的JDBC 4.0增強

          時間:2006-10-25
          作者:Srini Penchikala
          瀏覽次數: 5760
          本文關鍵字:JDOJDBCSQLJJavaSrini Penchikalajdbcmustangjava se 6RowIDdriverannotation驅動程序注釋
          文章工具
          推薦給朋友 推薦給朋友
          打印文章 打印文章

             Java Platform, Standard Edition(Java SE)版本6(代碼名稱Mustang)現在已經推出了第二個beta版本,并計劃于今年十月份交付使用。Java SE 6包括幾處對Java Database ConnectivityJDBC)API的增強。這些增強將被發布為JDBC 4.0版本。新JDBC功能的主要目標是提供更為簡單的設計方式和更好的開發人員體驗。本文概要說明了JDBC 4.0增強,以及它們給企業Java開發人員帶來的好處。我們將借助一個使用Apache Derby作為后端數據庫而構建的貸款處理示例應用程序,對新的JDBC功能進行探討。

          Java SE 6.0

            Java SE 6.0版本的主要目標是提供兼容性、穩定性和高質量。這個版本中有幾處有趣的增強,尤其是在監控與管理(JMX)、Web service、腳本語言支持(使用Rhino腳本引擎JSR 223將JavaScript技術與Java源代碼集成在一起)、數據庫連接性、注釋支持和安全性方面。JDBC API中還增加了幾個新功能,從新的RowId支持到更多的SQLException子類。

          JDBC 4.0功能

            借助Mustang中包含的Java SE Service Provider機制,Java開發人員不再需要使用像Class.forName()這樣的代碼顯式地加載JDBC驅動程序,就能注冊JDBC驅動程序。通過在調用DriverManager.getConnection()方法時自動定位合適的驅動程序,DriverManager類可以做到這一點。這個功能是向后兼容的,所以無需修改現有的JDBC代碼。

             在訪問關系數據庫的Java應用程序中,通過最小化我們需要編寫的“模板”代碼,JDBC 4.0還改善了開發人員體驗。它還提供實用程序類,以改進JDBC驅動程序的注冊和卸載機制,以及管理數據源和連接對象。

             借助JDBC 4.0,Java開發人員現在可以使用Annotations指定SQL查詢,從而利用Java SE 5.0(Tiger)版本中提供的元數據支持。基于注釋的SQL查詢允許在Java代碼中使用Annotation關鍵字指定SQL查詢字符串。這樣,我們就不必在兩個不同文件中查看JDBC代碼以及這些代碼中調用的數據庫查詢了。例如,如果有一個叫做getActiveLoans()的方法,用于獲取貸款處理數據庫中的當前貸款,可以使用@Query(sql="SELECT * FROM LoanApplicationDetails WHERE LoanStatus = 'A'")注釋來修飾它。

             此外,Java SE 6開發工具包(JDK 6)的最后版本——與運行時環境(JRE 6)相反——將會有一個基于與它綁定在一起的Apache Derby的數據庫。這將幫助開發人員理解新的JDBC功能,而不必單獨下載、安裝和配置數據庫產品。

             JDBC 4.0中加入的主要功能包括:

          • 自動加載JDBC驅動程序類。
          • 連接管理增強。
          • 支持RowId SQL 類型。
          • 使用Annotations的DataSet SQL實現。
          • 處理增強的SQL異常。
          • 支持SQL XML。

            還存在其他功能,比如對大對象(BLOB/CLOB)的改進支持和National Character Set Support。接下來的內容將會詳細分析這些功能。

          自動加載JDBC驅動程序

            在JDBC 4.0中,調用getConnection方法時,不再需要使用Class.forName()顯式地加載JDBC驅動程序,因為DriverManager將會試著從初始化時加載的以及使用與當前應用程序相同的類加載器顯式加載的JDBC驅動程序中,找出合適的驅動程序來。

             DriverManager方法getConnection和getDrivers已經增強為支持Java SE Service Provider機制(SPM)。根據SPM,服務被定義為一組眾所周知的接口和抽象類,而服務提供程序則是服務的特定實現。它還指定在META-INF/services目錄中保存服務提供程序配置文件。JDBC 4.0驅動程序必須包含文件META-INF/services/java.sql.Driver。這個文件包含JDBC驅動程序的java.sql.Driver實現的名稱。例如,要加載JDBC驅動程序以連接到Apache Derby數據庫,META-INF/services/java.sql.Driver文件就要包含以下項:

             org.apache.derby.jdbc.EmbeddedDriver

             讓我們盡快了解如何使用這項新功能加載JDBC驅動程序管理器。下面的列表顯示了加載JDBC驅動程序通常使用的示例代碼。我們假定需要連接到一個Apache Derby數據庫,因為我們在文章后面提到的示例應用程序中將使用這個數據庫:

           Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
          Connection conn
          
          =DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword);

            但是在JDBC 4.0中,我們不需要Class.forName()這一行。我們只要調用getConnection()就可以獲得數據庫連接。

             注意,這僅適用于在單機模式中獲得數據庫連接。如果使用某種數據庫連接池來管理連接,代碼將會有所區別。

          連接管理

            在JDBC 4.0之前,我們依賴于JDBC URL來定義數據源連接。現在有了JDBC 4.0,我們只要提供一組參數(比如主機名稱和端口號)給標準的連接工廠機制,就能獲得到任意數據源的連接。Connection和Statement接口中加入了新的方法,以便在管理池環境中的Statement對象時可以支持連接狀態跟蹤改進和更大的靈活性。元數據工具(JSR-175)用于管理活動連接。我們還可以獲得元數據信息,比如活動連接的狀態,還可以把連接指定為標準的(Connection,用于單機應用程序)、池化的(PooledConnection)或者甚至是用于XA事務的分布式連接(XAConnection)。注意,我們沒有直接使用XAConnection。它是由諸如WebLogic、WebSphere或JBoss這樣的Java EE應用服務器內部的事務管理器來使用的。

          RowId支持

            RowID接口被添加到JDBC 4.0中以支持ROWID數據類型,Oracle和DB2等數據庫也支持這種數據類型。當有多條記錄沒有惟一標識符列,而且需要在不允許復制的Collection(比如Hashtable)中保存查詢輸出時,RowId很有用。我們可以使用ResultSet的getRowId()方法來獲得RowId,并使用PreparedStatement的setRowId()方法在查詢中使用RowId。

             關于RowId對象要記住的一件重要事情是,分別在PreparedStatement和ResultSet中使用set或update方法時,RowId對象的值無法在數據源之間移植,可以認為它是特定于數據源的。所以,禁止在不同的Connection和ResultSet對象之間共享它。

             DatabaseMetaData中的getRowIdLifetime()方法可用于確定RowId對象的生存期有效性。表1中列出了返回值或行id可能取的值。

          RowId 值 描述
          ROWID_UNSUPPORTED 不支持ROWID數據類型。
          ROWID_VALID_OTHER RowID的生存期依賴于數據庫廠商實現。
          ROWID_VALID_TRANSACTION 只要在數據庫表中行未被刪除,RowID的生存期在當前的事務中。
          ROWID_VALID_SESSION 只要在數據庫表中行未被刪除,RowID的生存期在當前會話的持續時間中。
          ROWID_VALID_FOREVER 只要在數據庫表中行未被刪除,RowID的生存期是無限的。

          基于注釋的SQL查詢

            JDBC 4.0規范利用注釋(Java SE 5中加入)允許開發人員把SQL查詢與Java類關聯在一起,同時不用編寫大量的代碼。此外,通過使用Generics(JSR 014)和元數據(JSR 175)API,我們可以把SQL查詢與Java對象關聯在一起,從而指定查詢輸入和輸出參數。我們還可以把查詢結果綁定到Java類,以加速對查詢輸出的處理。我們無需編寫通常用于把查詢結果填充到Java對象中的所有代碼。在Java代碼中指定SQL查詢時,有2種主要的注釋:Select和Update。

          Select注釋

            Select注釋用于在Java類中指定選擇查詢,以便使用get方法從數據庫表中獲取數據。表2顯示了Select注釋的各種屬性以及它們的用法。

          名稱 類型 描述
          sql String SQL Select查詢字符串。
          value String 與sql屬性相同。
          tableName String 在其上調用sql的數據庫表的名稱。
          readOnly、connected、 scrollable Boolean 標志,分別用于指示返回的DataSet是只讀的還是可更新的,是否連接到后端數據庫,在connected模式中使用時是否可以滾動。
          allColumnsMapped Boolean 標志,用于指示sql注釋元素中的列名是否一對一地映射到DataSet中的字段。

            下面是Select注釋的一個例子,用于從貸款數據庫獲得所有當前貸款:

          interface LoanAppDetailsQuery extends BaseQuery {
          @Select("SELECT * FROM LoanDetais where LoanStatus = 'A'")
          DataSet<LoanApplication> getAllActiveLoans();
          }
          

            sql注釋也支持I/O參數(參數標記由一個問號后面跟一個整數來表示)。下面是參數化sql查詢的一個例子:

          interface LoanAppDetailsQuery extends BaseQuery {
          @Select(sql="SELECT * from LoanDetails
          where borrowerFirstName= 1 and borrowerLastName= 2")
          DataSet<LoanApplication> getLoanDetailsByBorrowerName(String borrFirstName,
          String borrLastName);
          }
          

          Update注釋

            Update注釋用于修飾Query接口方法,用于更新數據庫表中的一條或多條記錄。每個Update注釋都必須包含一個sql注釋類型的元素。下面是Update注釋的一個例子:

          interface LoanAppDetailsQuery extends BaseQuery {
          @Update(sql="update LoanDetails set LoanStatus = 1
          where loanId = 2")
          boolean updateLoanStatus(String loanStatus, int loanId);
          }
          

          處理增強的SQL異常

            異常處理是Java編程的一個重要組成部分,特別是當連接到后端關系數據庫或在后端關系數據庫上運行查詢的時候。我們一直使用SQLException類來指示與數據庫相關的錯誤。JDBC 4.0在SQLException處理方面有幾處增強。下面是JDBC 4.0版本中的一些增強,在處理SQLExceptions時它們可以為開發人員帶來更好的體驗:

          • 新的SQLException子類
          • 支持因果關系
          • 支持增強的for-each循環

          新的SQLException類

            JDBC 4.0中創建了SQLException的新子類,以便為Java程序員提供一種編寫更多可移植錯誤處理代碼的手段。JDBC 4.0中引入了2類新的SQLException:

          • SQL非瞬時異常
          • SQL瞬時異常

            非瞬時異常:同一項操作重試失敗時拋出此異常,直到SQLException的原因得到糾正為止。表3顯示了JDBC 4.0中加入的新異常類,它們都是SQLNonTransientException的子類(SQLState類值定義在SQL 2003規范中。):

          異常類 SQLState值
          SQLFeatureNotSupportedException 0A
          SQLNonTransientConnectionException 08
          SQLDataException 22
          SQLIntegrityConstraintViolationException 23
          SQLInvalidAuthorizationException 28
          SQLSyntaxErrorException 42

            瞬時異常:當操作在沒有任何應用程序級功能進行干涉的情況下重試,前面失敗的JDBC操作能夠成功時拋出此異常。表4中列出了對SQLTransientException進行擴展的新異常。

          異常類 SQLState值
          SQLTransientConnectionException 08
          SQLTransactionRollbackException 40
          SQLTimeoutException None

          因果關系

            現在,SQLException類支持配備有異常機制(也稱為Cause工具)的Java SE,這種機制讓我們能夠處理JDBC操作中拋出的多種異常(如果后端數據庫支持多異常功能)。這種場景發生在執行一條可能拋出多個SQLException的語句時。

             我們可以使用SQLException中的getNextException()方法,通過異常鏈進行迭代。下面給出一些用于處理SQLException因果關系的示例代碼:

          catch(SQLException ex) {
          while(ex != null) {
          LOG.error("SQL State:" + ex.getSQLState());
          LOG.error("Error Code:" + ex.getErrorCode());
          LOG.error("Message:" + ex.getMessage());
          Throwable t = ex.getCause();
          while(t != null) {
          LOG.error("Cause:" + t);
          t = t.getCause();
          }
          ex = ex.getNextException();
          }
          }
          

          增強的For-Each循環

            SQLException類實現了Iterable接口,為Java SE 5中加入的for-each循環功能提供支持。循環的導航將遍歷SQLException及其原因。下面給出一個代碼片段,對SQLException中加入的for-each循環進行了說明。

          catch(SQLException ex) {
          for(Throwable e : ex ) {
          LOG.error("Error occurred: " + e);
          }
          }

          對國家字符集轉換的支持

            下面列出了處理國家字符集(National Character Set)時JDBC類中所做的增強:

          • JDBC數據類型:加入了新的JDBC數據類型,比如NCHAR、NVARCHAR、LONGNVARCHAR和NCLOB。
          • PreparedStatement:加入了新方法setNString、setNCharacterStream和setNClob。
          • CallableStatement:加入了新方法getNClob、getNString和getNCharacterStream。
          • ResultSet:接口加入了新方法updateNClob、updateNString和updateNCharacterStream。

          對大對象(BLOB和CLOB)的增強支持

            下面列出了JDBC 4.0中對處理LOB所做的增強:

          • Connection:加入了新方法(createBlob()、createClob()和createNClob())以創建BLOB、CLOB和NCLOB對象的新實例。
          • PreparedStatement:加入了新方法setBlob()、setClob()和setNClob(),以便使用InputStream對象插入BLOB對象,以及使用Reader對象插入CLOB和NCLOB對象。
          • LOB:Blob、Clob和NClob接口中加入了新方法(free()),以便釋放這些對象占用的資源。

            現在,讓我們看一看java.sql和javax.jdbc包中加入的一些新類,以及它們提供了哪些服務。

          JDBC 4.0 API:新類

          RowId (java.sql)

            正如前面提過的那樣,這個接口代表著數據庫中的一個SQL ROWID值。ROWID是一個內置的SQL數據類型,用于識別數據庫表中的特定數據行。ROWID通常用在這樣的查詢中:該查詢從輸出行沒有惟一ID列的表中返回行。

             CallableStatement、PreparedStatement和ResultSet接口中的方法,比如getRowId和setRowId,允許程序員訪問SQL ROWID值。接口還提供一個方法(叫做getBytes())把ROWID的值返回為字節數組。DatabaseMetaData接口有一個叫做getRowIdLifetime的新方法,可用于確定RowId對象的生存期。RowId的作用域可以是下列3種類型之一:

          • 在其中創建RowId的數據庫事務的持續時間。
          • 在其中創建RowId的會話的持續時間。
          • 數據庫表中的標識行,只要它尚未被刪除。

          DataSet (java.sql)

            DataSet接口為從執行SQL查詢返回的數據提供類型安全的視圖。DataSet可以在已連接或未連接模式中進行操作。當在已連接模式中使用時,其功能類似于ResultSet。而在未連接模式中使用時,DataSet的功能則類似于CachedRowSet。因為DataSet擴展了List接口,我們可以遍歷查詢返回的行。

             現有的類中還加入了幾個新方法,比如Connection(createSQLXML、isValid)和ResultSet(getRowId)。

          示例應用程序

            本文中使用的示例應用程序是一個貸款處理應用程序,它包含一個貸款查找頁面,用戶可以在這個頁面上輸入一個貸款ID以獲得有關貸款的詳細信息,然后提交表單。貸款查找頁面調用一個控制器對象,而此控制器對象又調用DAO對象來訪問后端數據庫,從而獲得有關貸款的詳細信息。這些詳細信息包括借款人姓名、貸款金額和貸款到期時間,它們均會顯示在一個貸款詳細信息頁面上。在后端數據庫中,我們使用一個叫做LoanApplicationDetails的表來保存貸款應用程序的詳細信息。

             示例應用程序的用例是獲得特定貸款ID的貸款詳細信息。在注冊貸款并針對抵押產品和利率鎖定它之后,就可以獲得這些貸款詳細信息了。貸款處理應用程序的項目細節如表5所示。

          名稱
          Project Name JdbcApp
          Project Directory c:\dev\projects\JdbcApp
          DB Directory c:\dev\dbservers\apache\derby
          JDK Directory c:\dev\java\jdk_1.6.0
          IDE Directory c:\dev\tools\eclipse
          Database Apache Derby 10.1.2.1
          JDK 6.0 (beta 2 release)
          IDE Eclipse 3.1
          Unit Testing JUnit 4
          Build Ant 1.6.5

            下表列出了連接貸款詳細信息Apache Derby數據庫時需要用到的JDBC參數。這些參數都保存在一個叫做derby.properties的文本文件中,該文件位于項目基目錄下的etc/jdbc目錄中(參見表6)。

          名稱
          JDBC Driver File LoanApp\META-INF\services\java.sql.driver
          Driver org.apache.derby.ClientDriver
          URL jdbc:derby:derbyDB
          User Id user1
          Password user1

            注意:Apache Derby數據庫提供2類JDBC驅動程序:Embedded Driver(org.apache.derby.jdbc.EmbeddedDriver)和Client/Server Driver(org.apache.derby.jdbc.ClientDriver)。在示例應用程序中我使用的是Client/Server Driver版本。

             下面給出用于啟動Derby數據庫服務器和使用ij工具創建新數據庫的命令。

             要啟動Derby Network Server,打開一個命令提示,然后運行以下命令(修改DERBY_INSTALL和JAVA_HOME環境變量,從而影響本地環境)。

          set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.2.1-bin
          set JAVA_HOME=C:\dev\java\jdk1.6.0
          set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.3.1-bin
          set CLASSPATH=%CLASSPATH%;%DERBY_INSTALL%\lib\derby.jar;
          %DERBY_INSTALL%\lib\derbytools.jar;
          %DERBY_INSTALL%\lib\derbynet.jar;
          cd %DERBY_INSTALL%\frameworks\ NetworkServer\bin
          startNetworkServer.bat
          

            要連接到數據庫服務器和創建測試數據庫,打開另一個命令提示,然后運行以下命令。確保修改了DERBY_INSTALL和JAVA_HOME環境變量,以適應環境。

          set JAVA_HOME=C:\dev\java\jdk1.6.0
          set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.3.1-bin
          set CLASSPATH=%DERBY_INSTALL%\lib\derbyclient.jar;
          %DERBY_INSTALL%\lib\derbytools.jar;.
          %JAVA_HOME%\bin\java org.apache.derby.tools.ij
          connect 'jdbc:derby://localhost:1527/LoanDB;create=true';
          

          測試

            用于編譯Java源代碼的classpath設置應該包含位于項目主目錄下lib目錄中的derby.jarjunit4.jar文件。我們還需要在classpath中包含etcetc/jdbcetc/log4j目錄,這樣應用程序就能訪問JDBC屬性和Log4J配置文件。我創建了一個Ant編譯腳本(位于JdbcApp/build目錄中),以自動化編譯和打包Java代碼的任務。

             用于測試貸款詳細信息數據訪問對象的測試類叫做LoanAppDetailsDAOTest。我們傳入參數(比如貸款ID和借款人姓名)以獲得貸款詳細信息。

             下面的內容給出了一些代碼示例,這些代碼是關于JDBC 4.0規范的JDBC驅動程序自動加載和給予注釋的SQL查詢功能的。

          自動加載JDBC驅動程序

            BaseDAO抽象類有一個叫做getConnection的方法,用于獲得一個數據庫連接。下面的代碼片段顯示了這個方法(注意,我們不必注冊JDBC驅動程序)。只要java.sql.Driver文件中存在正確的驅動程序名稱(org.apache.derby.jdbc.ClientDriver),就可以自動加載JDBC驅動程序。

          protected Connection getConnection() throws DAOException {
          // Load JDBC properties first
          if (jdbcUrl == null || jdbcUser == null ||
          jdbcPassword == null) {
          loadJdbcProperties();
          }
          // Get Connection
          Connection conn = null;
          try {
          conn = DriverManager.getConnection(jdbcUrl, jdbcUser,
          jdbcPassword);
          } catch (SQLException sqle) {
          throw new DAOException("Error in getting a DB connection.",
          sqle);
          }
          return conn;
          }
          

          SQL注釋

            LoanAppDetailsQuery接口有帶有注釋的SQL查詢,用于獲得當前貸款(條件是loanstatus="A")的列表和基于貸款人姓名的貸款詳細信息(在一個貸款人借貸多筆款項的情況下)。我們在本文的前面部分曾見過這些SQL注釋。下面給出的示例代碼說明了如何調用使用Annotation定義的SQL查詢。

          public DataSet<LoanAppDetails> getAllActiveLoans() throws Exception {
          // Get Connection
          Connection conn = getConnection();
          LoanAppDetailsQuery query = null;
          DataSet<LoanAppDetails> loanDetails = null;
          query = QueryObjectFactory.createQueryObject(
          LoanAppDetailsQuery.class, conn);
          loanDetails = query.getAllActiveLoans();
          return loanDetails;
          }
          
          public DataSet<LoanAppDetails> getLoanDetailsByBorrowerName(
          String borrFirstName, String borrLastName) throws Exception {
          // Get Connection
          Connection conn = getConnection();
          LoanAppDetailsQuery query = null;
          DataSet<LoanAppDetails> loanDetails = null;
          query = QueryObjectFactory.createQueryObject(
          LoanAppDetailsQuery.class, conn);
          loanDetails = query.getLoanDetailsByBorrowerName(
          borrFirstName,borrLastName);
          return loanDetails;
          }
          

          結束語

            在使用SQL時,JDBC 4.0可以提供開發的簡便性并改善開發人員體驗。JDBC 4.0的另一個目標是提供企業級的JDBC功能,把API公開給涵蓋范圍更廣的工具集,以便更好地管理JDBC資源。此外,JDBC 4.0 API為JDBC驅動程序提供了一條遷移路徑,從而與J2EE Connector架構(JCA)保持兼容。這使得JDBC廠商能夠繼續實現JDBC技術Connector API。當在企業級面向服務架構(Service Oriented Architecture,SOA)應用程序中使用JDBC數據源時,這一點很重要,因為在企業級SOA應用程序中,可以把JDBC數據源部署為企業服務總線(Enterprise Service Bus,ESB)架構中的另一個適配器,而不必為JDBC數據源編寫ESB特定實現代碼。

             在本文中,我們討論了JDBC 4.0中的增強,比如RowId支持、JDBC驅動程序加載和基于Annotations的SQL。JDBC 4.0中還將加入其他功能,以便在未來支持SQL 2003規范。要了解有關JDBC 4.0規范的更多信息,請參考規范文檔。

          參考資料

           作者簡介
          Srini Penchikala 是一位在Flagstar銀行工作的信息系統學科問題專家。
          posted @ 2007-07-02 19:39 和田雨 閱讀(692) | 評論 (0)編輯 收藏

          主要特色:
          1.使用最新的JDBC3.0數據庫驅動。
          2.大幅度減化了JSP的反復調用JavaBean,可以直接寫SQL,無須再使用連接數據庫連接池。
          3.將大量的工作交給JavaBean做,JSP負責頁面控制。
          4.最大特色是極其簡單,程序編寫也極其簡單,非常適合初學者。
          5.使用的是tomcat數據庫連接池,方便快速。
          請提供E_mail,為大家分享,如有高手,請指點不是。
          本人E_mail:c841@163.com,望多提意見。
          ****************************************文件名《page.jsp》*******************************************************************
          文件名《page.jsp》
          <%@ page language="java" import="java.sql.*, my.*" %>
          <%@ page contentType="text/html; charset=gb2312" %>
          <jsp:useBean id="pagi" scope="page" class="my.Pagi"/>
          <html>
          <body>
          <table  align="center" border=1>
          <%
          String CountQuery="select count(*) from 商品資料";
          String query = "select * from 商品資料";
          ResultSet rs = pagi.querySql(CountQuery,query, request);
          String footer = pagi.PageFooter();
          %>
          <tr>
          <td >商品編號</font></td>
          <td >商品名稱</font></td>
          </tr>
          <%
          if (pagi.intPageCount>0)
          {
          int i=0;
          while (rs.next())
          {
          i++;
          if (i>((pagi.intPage-1)*pagi.intPageSize) &&(i<=pagi.intPage*pagi.intPageSize))
          {
          %>
          <tr>
          <td><%=rs.getString(1)%></td>
          <td><%=rs.getString(2)%></td>
          </tr>
          <%
          }
          }
          }
          out.println("<tr><td colspan=2>"+footer+"</td></tr>");
          rs.close();
          pagi.close_all();
          %>
          </table>
          </body>
          </html>
          ****************************************文件名《pagi.java》*********************************************************
          文件名《pagi.java》
          package my;
          import java.util.*;
          import java.sql.*;
          import java.io.*;
          import javax.servlet.*;
          import javax.servlet.http.*;
          import my.DB.*;
          public class Pagi
          {
          ResultSet CountTopicrs=null; //初始化總記錄數Rs變量
          ResultSet Pagirs=null; //初始化分頁時Rs變量
          public int intCountTopic=0; //主題總數
          public int intPageSize;//每頁顯示主題數
          public int intPageCount;//總頁數
          public int intPage=1; //當前頁數
          public String nowPage; // int i;
          public String HttpFile;//初始化當前頁intPage變量,以準確便獲取當前頁。 //當前的地址欄的文件
          DB db; //定義Linkdb類的一個對象。
          public Pagi()//定義構造器,初始化每頁顯示的主題數和數據庫的連接。
          {
          intPageSize=4;  //每頁顯示的記錄數目
          db = new DB();
          }
          //Countsql:總記錄的Query字符串。[形式為select count(*) from tablename]
          //Pagisql :要分頁的Query字符串。[形式為select * from tablename where ...]
          //request :參數傳遞過程中的變量。[用來控制翻頁時的pages變量]
          public ResultSet querySql(String Countsql,String Pagisql,HttpServletRequest request)throws Exception
          {
          HttpFile=request.getRequestURI();  //獲取當前文件名。
          nowPage=request.getParameter("pages");  //獲取當前頁,將數值賦予intPage變量。[分頁欄中必須要有pages參數]
          if (nowPage==null)
          {
          intPage=1;
          }
          else
          {
          intPage=Integer.parseInt(nowPage);
          if (intPage<1)
          intPage=1;
          }
          CountTopicrs=db.executeQuery(Countsql); //@@@@@@@@@@@@獲取總記錄數的結果集。
          if (CountTopicrs.next())
          {
          intCountTopic=CountTopicrs.getInt(1);
          }
          intPageCount = (intCountTopic+intPageSize-1)/intPageSize;  //獲取總頁數。
          if (intPage>intPageCount)//如果當前頁大于總頁數,則當前頁等于總頁數。
          {
          intPage=intPageCount;
          }
          CountTopicrs.close();  //關閉總主題數的數據集。
          db.close_all();
          Pagirs=db.executeQuery(Pagisql);  //@@@@@@@@@@@@@@@獲取執行分頁的結果集。
          return Pagirs;
          }//end querySql function.
          public int getCountTopic()//獲取記錄總數。
          {
          return intCountTopic;
          }
          public int getPageCount() //獲取總頁數。
          {
          return intPageCount;
          }
          public int getIntPage()  //獲取當前頁數。
          {
          return intPage;
          }
          public String PageFooter()
          {
          String str = "";
          int next, prev;
          prev=intPage-1;
          next=intPage+1;
          str += "查詢到<font color=red>"+getCountTopic()+"</font>條記錄"+
          "    共<font color=red>"+getPageCount()+"</font>頁";
          str +=" 第<font color=red>"+getIntPage()+"</font>頁 ";
          if(intPage>1)
          str += " <A href=" + HttpFile + "?pages=1"+">首頁</A> ";
          else
          str += " 首頁 ";
          if(intPage>1)
          str += " <A href=" + HttpFile + "?pages=" + prev + ">上一頁</A> ";
          else
          str += " 上一頁 ";
          if(intPage<intPageCount)
          str += " <A href=" + HttpFile + "?pages=" + next + ">下一頁</A> ";
          else
          str += " 下一頁 ";
          if(intPageCount>1&&intPage!=intPageCount)
          str += " <A href=" + HttpFile + "?pages=" + intPageCount +
          ">尾頁</A>";
          else
          str += " 尾頁 ";
          return str;
          }
          public void close_all()
          {
          db.close_all();
          }
          }
          ************************************************文件名《DB.java》********************************************************
          文件名《DB.java》
          package my;
          import java.sql.*;
          import javax.naming.*;
          import javax.sql.DataSource;
          //一個用于查找數據源的工具類。
          public class DB {
          private Connection con=null;
          private Statement stmt=null;
          ResultSet rs=null;
          public  ResultSet executeQuery(String sql) throws Exception
          {
          rs=null;
          try
          {
          Context initCtx = new javax.naming.InitialContext();
          Context envCtx = (Context) initCtx.lookup("java:comp/env");
          DataSource ds = (DataSource)envCtx.lookup("jdbc/bn");
          con=ds.getConnection();
          stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
          rs=stmt.executeQuery (sql);
          }
          catch(SQLException e){throw e;}
          catch(NamingException e){throw e;}
          return rs;
          }
          //執行Insert,Update語句
          public void executeUpdate(String sql) throws Exception
          {
          stmt = null;
          rs=null;
          try
          {
          Context initCtx = new javax.naming.InitialContext();
          Context envCtx = (Context) initCtx.lookup("java:comp/env");
          DataSource ds = (DataSource)envCtx.lookup("jdbc/bn");
          con=ds.getConnection();
          stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
          stmt.executeQuery(sql);
          stmt.close();
          con.close();
          }
          catch(SQLException ex)
          {
          System.err.println("執行SQL語句出錯: " + ex.getMessage());
          }
          }
          // 關閉stmt和關閉連接
          public void close_all()
          {
          try{
          stmt.close();
          con.close();
          }
          catch(SQLException e){e.printStackTrace();}
          }
          }
          ***************************************《tomcat中的數據庫連接池的設置》********************************************************************************
          ……
          ……
          ……
          <Context path="/SQL" docBase="D:\SQL_JSP" debug="0" reloadable="true" crossContext="true">
          <Resource name="jdbc/bn" auth="Container" type="javax.sql.DataSource"/>
          <ResourceParams name="jdbc/bn">
          <parameter>
          <name>factory</name>
          <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
          </parameter>
          <parameter>
          <name>driverClassName</name>
          <value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>
          </parameter>
          <parameter>
          <name>url</name>
          <value>jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=jspdev</value>
          </parameter>
          <parameter>
          <name>username</name>
          <value>cyg</value>
          </parameter>
          <parameter>
          <name>password</name>
          <value>325345353</value>
          </parameter>
          <parameter>
          <name>maxActive</name>
          <value>20</value>
          </parameter>
          <parameter>
          <name>maxIdle</name>
          <value>20</value>
          </parameter>
          <parameter>
          <name>maxWait</name>
          <value>-1</value>
          </parameter>
          </ResourceParams>
          </Context>
          </Host>
          </Engine>
          </Service>
          </Server>
          
          posted @ 2007-07-02 19:23 和田雨 閱讀(963) | 評論 (0)編輯 收藏

          目前所有的B/S系統應用可以分為:有狀態(statefull)和無狀態(stateless)兩大類別。 有狀態是指在整個系統的處理過程中要保留記住一些信息,而無狀態則相反,每次request都是獨立的連接,不需要在每個request之間共享數據等等。

          對于這兩種應用,通常第一考慮是性能要最優,性能是我們選擇IT技術的主要依據之一。

          為達到最大化的性能,對于Java系統,以前通常的作法是使用對象池,這樣節約對象生成時的性能開銷,也就是說系統啟動時,預先生成一定數目的對象實例在內存中,需要使用時,從對象池中取出實例,用完,歸還對象池,對于有狀態的應用,可以使用相關持久化(persistence)策略來保存狀態。

          下一步,如何并行訪問對象池將是非常重要,java的多線程技術為我們提供了實現可能,線程的創建銷毀也是可能非常耗時的,那么,無疑象使用對象池一樣,我們必須使用線程池來實現多線程并行計算的最優化。

          使用線程池和對象池,每次客戶端請求發生一次就從線程池中借用一個線程,處理完這個請求就將線程返回線程池,同樣,使用線程快速的訪問對象,對象也是從對象池中借用,用完就還回對象池。 整個這樣的架構設計在性能上是最優的。

          有了性能保證,安全機制、事務機制、集群(cluster)技術也將是選擇IT技術的主要依據。

          J2EE就是這樣一個實現上述多種考量的綜合標準框架系統,在具體使用中,也許我們對所有這些考量的要求并不都一樣重視,比如:如果純粹追求性能是第一,可以忽視事務機制,那么,完整的J2EE技術也許就并不適合你。

          那么我們先看看J2EE是如何從性能上保證我們的應用系統以最快速度運行的,也就是說J2EE中必然應該有上述線程池和對象池的實現技術,servlet實際是基于線程池的更好的線程容器;EJB是基于對象池的更好的對象容器。

          看看Servler的架構圖:

           

          當client1發生請求時servlet容器會從線程池中分配一個線程給這個request.


          再看看EJB的架構圖:



          instance Pool作為一個對象實例池,維持著EJB實例,當然這個對象池是用生命周期的,簡單的說 EJB=對象池+遠程對象池

          但是,EJB還整合了相當的其它增強功能,如安全 事務機制等,這些對于一般應用都是必需的,當然你還必須根據你的需要來選擇是否使用J2EE,如果你的應用對安全 事務機制沒有要求,直接使用線程池和對象池技術肯定獲得最好的性能。

          所以,根據Servler和EJB的原理,我們已經可以規劃我們的應用,什么可以放在servlet,或什么需要放在EJB中實現:

          線程的本質決定了servlet只適合一些輕量的應用,如分析簡單XML文檔, 通過JDBC訪問數據源,使用JMS或JavaMail處理簡單的信息Message,或使用JTS/JTA處理簡單的事務機制,注意這些用詞都是"簡單"的,一旦復雜了,就要使用EJB了。

          下面從客戶端和服務器端兩個方面來具體考量這兩個技術的使用,這里的客戶端不一定是指最終客戶端,因為J2EE是多層結構,中間層可能在多個服務器上實現,如果一個服務器上的服務是供另外一個服務器上的應用訪問的,那么后者我們也稱為客戶端。

          根據應用的復雜程度和要求不同,分下列情況:

          1.在WEB層可以實現的一些應用

          如果你的系統沒有很復雜的事務處理,或訪問很多企業原有的資源,那么可以借助javabean這樣的一些Help性質的類來實現你的應用,但是,這樣的方案不是最干凈clean, 最有效efficient, 或最有擴展性的scalable。

          否則,將所有核心計算放置入EJB中。

          2.所有的復雜商務計算核心都在EJB中完成

          如果你的客戶端和服務器端之間有防火墻,那么目前能夠無障礙通過防火墻的協議只有Http了(Web Service也是基于http就是這個道理),既然使用http了,而Servlet是基于Http協議的,那么就需要通過servlet來訪問EJB,這是我們最普遍的應用情況。

          但是,如果你的客戶端和服務器端可以放置在一個網絡內,之間沒有防火墻,那么就不必使用Servlet,直接使用Java調用RMI來訪問EJB,這樣性能是最好的,這時的Servlet大概只有用于控制Jsp的頁面的輸出了(MVC模式中的控制作用)。

          如果是非java客戶端,可以通過CORBA組件來訪問EJB。

          3.如果你的應用對速度要求很高,要求非常快,對于事務處理等方面幾乎無要求

          直接使用J2SE,加上線程池和對象池技術,將會使你的java系統性能發揮極致。Jakarta.Apache.org有這兩種技術的源碼,線程池可以從Servlet容器Tomcat的源碼中發現。

          posted @ 2007-07-02 19:19 和田雨 閱讀(228) | 評論 (0)編輯 收藏

            1.RequestDispatcher.forward()

            是在服務器端起作用,當使用forward()時,Servlet engine傳遞HTTP請求從當前的Servlet or JSP到另外一個Servlet,JSP 或普通HTML文件,也即你的form提交至a.jsp,在a.jsp用到了forward()重定向至b.jsp,此時form提交的所有信息在b.jsp都可以獲得,參數自動傳遞.

            但forward()無法重定向至有frame的jsp文件,可以重定向至有frame的html文件,同時forward()無法在后面帶參數傳遞,比如servlet?name=frank,這樣不行,可以程序內通過response.setAttribute("name",name)來傳至下一個頁面.

            重定向后瀏覽器地址欄URL不變.

            例:在servlet中進行重定向

            public void doPost(HttpServletRequest request,HttpServletResponse response)

            throws ServletException,IOException

            {

            response.setContentType("text/html; charset=gb2312");

            ServletContext sc = getServletContext();

            RequestDispatcher rd = null;

            rd = sc.getRequestDispatcher("/index.jsp");   //定向的頁面

            rd.forward(request, response);

            }

            通常在servlet中使用,不在jsp中使用。

            2.response.sendRedirect()

            是在用戶的瀏覽器端工作,sendRedirect()可以帶參數傳遞,比如servlet?name=frank傳至下個頁面,同時它可以重定向至不同的主機上,sendRedirect()可以重定向有frame.的jsp文件.

            重定向后在瀏覽器地址欄上會出現重定向頁面的URL

            例:在servlet中重定向

            public void doPost(HttpServletRequest request,HttpServletResponse response)

            throws ServletException,IOException

            {

            response.setContentType("text/html; charset=gb2312");

            response.sendRedirect("/index.jsp");

            }

            由于response是jsp頁面中的隱含對象,故在jsp頁面中可以用response.sendRedirect()直接實現重定位。

            注意:

            (1).使用response.sendRedirect時,前面不能有HTML輸出。

            這并不是絕對的,不能有HTML輸出其實是指不能有HTML被送到了瀏覽器。事實上現在的server都有cache機制,一般在8K(我是說JSP SERVER),這就意味著,除非你關閉了cache,或者你使用了out.flush()強制刷新,那么在使用sendRedirect之前,有少量的HTML輸出也是允許的。

            (2).response.sendRedirect之后,應該緊跟一句return;

            我們已經知道response.sendRedirect是通過瀏覽器來做轉向的,所以只有在頁面處理完成后,才會有實際的動作。既然你已經要做轉向了,那么后的輸出還有什么意義呢?而且有可能會因為后面的輸出導致轉向失敗。

            比較:

            (1).Request Dispatcher.forward()是容器中控制權的轉向,在客戶端瀏覽器地址欄中不會顯示出轉向后的地址;

            (2).response.sendRedirect()則是完全的跳轉,瀏覽器將會得到跳轉的地址,并重新發送請求鏈接。這樣,從瀏覽器的地址欄中可以看到跳轉后的鏈接地址。

            前者更加高效,在前者可以滿足需要時,盡量使用RequestDispatcher.forward()方法.

            注:在有些情況下,比如,需要跳轉到一個其它服務器上的資源,則必須使用HttpServletResponse.sendRequest()方法。

            3.<jsp:forward page="" />

            它的底層部分是由RequestDispatcher來實現的,因此它帶有RequestDispatcher.forward()方法的印記。

            如果在<jsp:forward>之前有很多輸出,前面的輸出已使緩沖區滿,將自動輸出到客戶端,那么該語句將不起作用,這一點應該特別注意。

            另外要注意:它不能改變瀏覽器地址,刷新的話會導致重復提交

            4.修改HTTP header的Location屬性來重定向

            通過設置直接修改地址欄來實現頁面的重定向。
          jsp文件代碼如下:

            <%

            response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);

            String newLocn = "/newpath/jsa.jsp";

            response.setHeader("Location",newLocn);

            %>

            5.JSP中實現在某頁面停留若干秒后,自動重定向到另一頁面

            在html文件中,下面的代碼:

            <meta http-equiv="refresh" content="300; url=target.jsp">

            它的含義:在5分鐘之后正在瀏覽的頁面將會自動變為target.html這一頁。代碼中300為刷新的延遲時間,以秒為單位。targer.html為你想轉向的目標頁,若為本頁則為自動刷新本頁。

            由上可知,可以通過setHeader來實現某頁面停留若干秒后,自動重定向到另一頁面。

            關鍵代碼:

            String content=stayTime+";URL="+URL;

            response.setHeader("REFRESH",content);

            如果總結得不夠全面,請各位發表自己的意見或經驗。
          posted @ 2007-07-02 13:38 和田雨 閱讀(297) | 評論 (0)編輯 收藏

          http://www.stcore.com/java/2006-11-17/1163704120d113828.html
          posted @ 2007-07-02 13:34 和田雨 閱讀(256) | 評論 (0)編輯 收藏

          由于工作需要,最近在找一些解決方案,發現Listener是一個很好的東西, 能夠監聽到session,application的create,destroy,可以監聽到session,application

           屬性綁定的變化,考慮了一下,可以應用在"在線人數統計","數據緩存"等各個方面,

          下面是整理的一些資料.



          Listener是Servlet的監聽器,它可以監聽客戶端的請求、服務端的操作等。通過監聽器,可以自動激發一些操作,比如監聽在線的用戶的數量。當增加一個HttpSession時,就激發sessionCreated(HttpSessionEvent se)方法,這樣就可以給在線人數加1。常用的監聽接口有以下幾個:

          ServletContextAttributeListener監聽對ServletContext屬性的操作,比如增加、刪除、修改屬性。

          ServletContextListener監聽ServletContext。當創建ServletContext時,激發contextInitialized(ServletContextEvent sce)方法;當銷毀ServletContext時,激發contextDestroyed(ServletContextEvent sce)方法。

          HttpSessionListener監聽HttpSession的操作。當創建一個Session時,激發session Created(HttpSessionEvent se)方法;當銷毀一個Session時,激發sessionDestroyed (HttpSessionEvent se)方法。

          HttpSessionAttributeListener監聽HttpSession中的屬性的操作。當在Session增加一個屬性時,激發attributeAdded(HttpSessionBindingEvent se) 方法;當在Session刪除一個屬性時,激發attributeRemoved(HttpSessionBindingEvent se)方法;當在Session屬性被重新設置時,激發attributeReplaced(HttpSessionBindingEvent se) 方法。

          下面我們開發一個具體的例子,這個監聽器能夠統計在線的人數。在ServletContext初始化和銷毀時,在服務器控制臺打印對應的信息。當ServletContext里的屬性增加、改變、刪除時,在服務器控制臺打印對應的信息。

          要獲得以上的功能,監聽器必須實現以下3個接口:

          HttpSessionListener

          ServletContextListener

          ServletContextAttributeListener

          我們看具體的代碼,見示例14-9。

          【程序源代碼】

          1 // ==================== Program Discription =====================

          2 // 程序名稱:示例14-9 : EncodingFilter .java

          3 // 程序目的:學習使用監聽器

          4 // ==============================================================

          5 import javax.servlet.http.*;

          6 import javax.servlet.*;

          7

          8 public class OnLineCountListener implements HttpSessionListener,

          ServletContextListener,ServletContextAttributeListener

          9 {

          10  private int count;

          11  private ServletContext context = null;

          12  

          13  public OnLineCountListener()

          14  {

          15   count=0;

          16   //setContext();

          17  }

          18  //創建一個session時激發

          19  public void sessionCreated(HttpSessionEvent se)

          20  {

          21   count++;

          22   setContext(se);

          23   

          24  }

          25  //當一個session失效時激發

          26  public void sessionDestroyed(HttpSessionEvent se)

          27  {

          28   count--;

          29   setContext(se);

          30  }

          31  //設置context的屬性,它將激發attributeReplaced或attributeAdded方法

          32  public void setContext(HttpSessionEvent se)

          33  {

          34   se.getSession().getServletContext().
          posted @ 2007-07-02 13:33 和田雨 閱讀(1092) | 評論 (2)編輯 收藏

          1.RequestDispatcher.forward()

          是在服務器端起作用,當使用forward()時,Servlet engine傳遞HTTP請求從當前的Servlet or JSP到另外一個Servlet,JSP 或普通HTML文件,也即你的form提交至a.jsp,在a.jsp用到了forward()重定向至b.jsp,此時form提交的所有信息在 b.jsp都可以獲得,參數自動傳遞.

          但forward ()無法重定向至有frame的jsp文件,可以重定向至有frame的html文件,同時forward()無法在后面帶參數傳遞,比如 servlet?name=frank,這樣不行,可以程序內通過response.setAttribute("name",name)來傳至下一個頁面.

          重定向后瀏覽器地址欄URL不變.

          例:servlet文件中重定向
          CODE

          public void doPost(HttpServletRequest request,HttpServletResponse response)

                 throws ServletException,IOException

          {

                 response.setContentType("text/html; charset=gb2312");

                 ServletContext sc = getServletContext();

                 RequestDispatcher rd = null;

                 rd = sc.getRequestDispatcher("/index.jsp");

                 rd.forward(request, response);
          }


          2.response.sendRedirect()

          是在用戶的瀏覽器端工作,sendRedirect()可以帶參數傳遞,比如servlet?name=frank傳至下個頁面,同時它可以重定向至不同的主機上,且在瀏覽器地址欄上會出現重定向頁面的URL.

          sendRedirect()可以重定向有frame的jsp文件.

          例:servlet文件中重定向
          CODE

          public void doPost(HttpServletRequest request,HttpServletResponse response)

                 throws ServletException,IOException

          {

                 response.setContentType("text/html; charset=gb2312");

                 response.sendRedirect("/index.jsp");

          }

          posted @ 2007-07-02 13:31 和田雨 閱讀(257) | 評論 (0)編輯 收藏

          創建型模式

          1、FACTORY—追MM少不了請吃飯了,麥當勞的雞翅和肯德基的雞翅都是MM愛吃的東西,雖然口味有所不同,但不管你帶MM去麥當勞或肯德基,只管向服務員說“來四個雞翅”就行了。麥當勞和肯德基就是生產雞翅的Factory

          工廠模式:客戶類和工廠類分開。消費者任何時候需要某種產品,只需向工廠請求即可。消費者無須修改就可以接納新產品。缺點是當產品修改時,工廠類也要做相應的修改。如:如何創建及如何向客戶端提供。

          2、BUILDER—MM最愛聽的就是“我愛你”這句話了,見到不同地方的MM,要能夠用她們的方言跟她說這句話哦,我有一個多種語言翻譯機,上面每種語言都有一個按鍵,見到MM我只要按對應的鍵,它就能夠用相應的語言說出“我愛你”這句話了,國外的MM也可以輕松搞掂,這就是我的“我愛你”builder。(這一定比美軍在伊拉克用的翻譯機好賣)

          建造模式:將產品的內部表象和產品的生成過程分割開來,從而使一個建造過程生成具有不同的內部表象的產品對象。建造模式使得產品內部表象可以獨立的變化,客戶不必知道產品內部組成的細節。建造模式可以強制實行一種分步驟進行的建造過程。

          3、FACTORY METHOD—請MM去麥當勞吃漢堡,不同的MM有不同的口味,要每個都記住是一件煩人的事情,我一般采用Factory Method模式,帶著MM到服務員那兒,說“要一個漢堡”,具體要什么樣的漢堡呢,讓MM直接跟服務員說就行了。

          工廠方法模式:核心工廠類不再負責所有產品的創建,而是將具體創建的工作交給子類去做,成為一個抽象工廠角色,僅負責給出具體工廠類必須實現的接口,而不接觸哪一個產品類應當被實例化這種細節。

          4、PROTOTYPE—跟MM用QQ聊天,一定要說些深情的話語了,我搜集了好多肉麻的情話,需要時只要copy出來放到QQ里面就行了,這就是我的情話prototype了。(100塊錢一份,你要不要)

          原始模型模式:通過給出一個原型對象來指明所要創建的對象的類型,然后用復制這個原型對象的方法創建出更多同類型的對象。原始模型模式允許動態的增加或減少產品類,產品類不需要非得有任何事先確定的等級結構,原始模型模式適用于任何的等級結構。缺點是每一個類都必須配備一個克隆方法。

          5、SINGLETON—俺有6個漂亮的老婆,她們的老公都是我,我就是我們家里的老公Sigleton,她們只要說道“老公”,都是指的同一個人,那就是我(剛才做了個夢啦,哪有這么好的事)

          單例模式:單例模式確保某一個類只有一個實例,而且自行實例化并向整個系統提供這個實例單例模式。單例模式只應在有真正的“單一實例”的需求時才可使用。

          結構型模式

          6、ADAPTER—在朋友聚會上碰到了一個美女Sarah,從香港來的,可我不會說粵語,她不會說普通話,只好求助于我的朋友kent了,他作為我和Sarah之間的Adapter,讓我和Sarah可以相互交談了(也不知道他會不會耍我)

          適配器(變壓器)模式:把一個類的接口變換成客戶端所期待的另一種接口,從而使原本因接口原因不匹配而無法一起工作的兩個類能夠一起工作。適配類可以根據參數返還一個合適的實例給客戶端。

          7、BRIDGE—早上碰到MM,要說早上好,晚上碰到MM,要說晚上好;碰到MM穿了件新衣服,要說你的衣服好漂亮哦,碰到MM新做的發型,要說你的頭發好漂亮哦。不要問我“早上碰到MM新做了個發型怎么說”這種問題,自己用BRIDGE組合一下不就行了

          橋梁模式:將抽象化與實現化脫耦,使得二者可以獨立的變化,也就是說將他們之間的強關聯變成弱關聯,也就是指在一個軟件系統的抽象化和實現化之間使用組合/聚合關系而不是繼承關系,從而使兩者可以獨立的變化。

          8、COMPOSITE—Mary今天過生日。“我過生日,你要送我一件禮物。”“嗯,好吧,去商店,你自己挑。”“這件T恤挺漂亮,買,這條裙子好看,買,這個包也不錯,買。”“喂,買了三件了呀,我只答應送一件禮物的哦。”“什么呀,T恤加裙子加包包,正好配成一套呀,小姐,麻煩你包起來。”“……”,MM都會用Composite模式了,你會了沒有?

          合成模式:合成模式將對象組織到樹結構中,可以用來描述整體與部分的關系。合成模式就是一個處理對象的樹結構的模式。合成模式把部分與整體的關系用樹結構表示出來。合成模式使得客戶端把一個個單獨的成分對象和由他們復合而成的合成對象同等看待。

          9、DECORATOR—Mary過完輪到Sarly過生日,還是不要叫她自己挑了,不然這個月伙食費肯定玩完,拿出我去年在華山頂上照的照片,在背面寫上“最好的的禮物,就是愛你的Fita”,再到街上禮品店買了個像框(賣禮品的MM也很漂亮哦),再找隔壁搞美術設計的Mike設計了一個漂亮的盒子裝起來……,我們都是Decorator,最終都在修飾我這個人呀,怎么樣,看懂了嗎?

          裝飾模式:裝飾模式以對客戶端透明的方式擴展對象的功能,是繼承關系的一個替代方案,提供比繼承更多的靈活性。動態給一個對象增加功能,這些功能可以再動態的撤消。增加由一些基本功能的排列組合而產生的非常大量的功能。
          10、FACADE—我有一個專業的Nikon相機,我就喜歡自己手動調光圈、快門,這樣照出來的照片才專業,但MM可不懂這些,教了半天也不會。幸好相機有Facade設計模式,把相機調整到自動檔,只要對準目標按快門就行了,一切由相機自動調整,這樣MM也可以用這個相機給我拍張照片了。

          門面模式:外部與一個子系統的通信必須通過一個統一的門面對象進行。門面模式提供一個高層次的接口,使得子系統更易于使用。每一個子系統只有一個門面類,而且此門面類只有一個實例,也就是說它是一個單例模式。但整個系統可以有多個門面類。

          11、FLYWEIGHT—每天跟MM發短信,手指都累死了,最近買了個新手機,可以把一些常用的句子存在手機里,要用的時候,直接拿出來,在前面加上MM的名字就可以發送了,再不用一個字一個字敲了。共享的句子就是Flyweight,MM的名字就是提取出來的外部特征,根據上下文情況使用。

          享元模式:FLYWEIGHT在拳擊比賽中指最輕量級。享元模式以共享的方式高效的支持大量的細粒度對象。享元模式能做到共享的關鍵是區分內蘊狀態和外蘊狀態。內蘊狀態存儲在享元內部,不會隨環境的改變而有所不同。外蘊狀態是隨環境的改變而改變的。外蘊狀態不能影響內蘊狀態,它們是相互獨立的。將可以共享的狀態和不可以共享的狀態從常規類中區分開來,將不可以共享的狀態從類里剔除出去。客戶端不可以直接創建被共享的對象,而應當使用一個工廠對象負責創建被共享的對象。享元模式大幅度的降低內存中對象的數量。

          12、PROXY—跟MM在網上聊天,一開頭總是“hi,你好”,“你從哪兒來呀?”“你多大了?”“身高多少呀?”這些話,真煩人,寫個程序做為我的Proxy吧,凡是接收到這些話都設置好了自動的回答,接收到其他的話時再通知我回答,怎么樣,酷吧。

          代理模式:代理模式給某一個對象提供一個代理對象,并由代理對象控制對源對象的引用。代理就是一個人或一個機構代表另一個人或者一個機構采取行動。某些情況下,客戶不想或者不能夠直接引用一個對象,代理對象可以在客戶和目標對象直接起到中介的作用。客戶端分辨不出代理主題對象與真實主題對象。代理模式可以并不知道真正的被代理對象,而僅僅持有一個被代理對象的接口,這時候代理對象不能夠創建被代理對象,被代理對象必須有系統的其他角色代為創建并傳入。

          行為模式

          13、CHAIN OF RESPONSIBLEITY—晚上去上英語課,為了好開溜坐到了最后一排,哇,前面坐了好幾個漂亮的MM哎,找張紙條,寫上“Hi,可以做我的女朋友嗎?如果不愿意請向前傳”,紙條就一個接一個的傳上去了,糟糕,傳到第一排的MM把紙條傳給老師了,聽說是個老處女呀,快跑!

          責任鏈模式:在責任鏈模式中,很多對象由每一個對象對其下家的引用而接

          起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。客戶并不知道鏈上的哪一個對象最終處理這個請求,系統可以在不影響客戶端的情況下動態的重新組織鏈和分配責任。處理者有兩個選擇:承擔責任或者把責任推給下家。一個請求可以最終不被任何接收端對象所接受。

          14、COMMAND—俺有一個MM家里管得特別嚴,沒法見面,只好借助于她弟弟在我們倆之間傳送信息,她對我有什么指示,就寫一張紙條讓她弟弟帶給我。這不,她弟弟又傳送過來一個COMMAND,為了感謝他,我請他吃了碗雜醬面,哪知道他說:“我同時給我姐姐三個男朋友送COMMAND,就數你最小氣,才請我吃面。”,:-(

          命令模式:命令模式把一個請求或者操作封裝到一個對象中。命令模式把發出命令的責任和執行命令的責任分割開,委派給不同的對象。命令模式允許請求的一方和發送的一方獨立開來,使得請求的一方不必知道接收請求的一方的接口,更不必知道請求是怎么被接收,以及操作是否執行,何時被執行以及是怎么被執行的。系統支持命令的撤消。

          15、INTERPRETER—俺有一個《泡MM真經》,上面有各種泡MM的攻略,比如說去吃西餐的步驟、去看電影的方法等等,跟MM約會時,只要做一個Interpreter,照著上面的腳本執行就可以了。

          解釋器模式:給定一個語言后,解釋器模式可以定義出其文法的一種表示,并同時提供一個解釋器。客戶端可以使用這個解釋器來解釋這個語言中的句子。解釋器模式將描述怎樣在有了一個簡單的文法后,使用模式設計解釋這些語句。在解釋器模式里面提到的語言是指任何解釋器對象能夠解釋的任何組合。在解釋器模式中需要定義一個代表文法的命令類的等級結構,也就是一系列的組合規則。每一個命令對象都有一個解釋方法,代表對命令對象的解釋。命令對象的等級結構中的對象的任何排列組合都是一個語言。



          16、ITERATOR—我愛上了Mary,不顧一切的向她求婚。

          Mary:“想要我跟你結婚,得答應我的條件”

          我:“什么條件我都答應,你說吧”

          Mary:“我看上了那個一克拉的鉆石”

          我:“我買,我買,還有嗎?”

          Mary:“我看上了湖邊的那棟別墅”

          我:“我買,我買,還有嗎?”

          Mary:“你的小弟弟必須要有50cm長”

          我腦袋嗡的一聲,坐在椅子上,一咬牙:“我剪,我剪,還有嗎?”

          ……

          迭代子模式:迭代子模式可以順序訪問一個聚集中的元素而不必暴露聚集的內部表象。多個對象聚在一起形成的總體稱之為聚集,聚集對象是能夠包容一組對象的容器對象。迭代子模式將迭代邏輯封裝到一個獨立的子對象中,從而與聚集本身隔開。迭代子模式簡化了聚集的界面。每一個聚集對象都可以有一個或一個以上的迭代子對象,每一個迭代子的迭代狀態可以是彼此獨立的。迭代算法可以獨立于聚集角色變化。

          17、MEDIATOR—四個MM打麻將,相互之間誰應該給誰多少錢算不清楚了,幸虧當時我在旁邊,按照各自的籌碼數算錢,賺了錢的從我這里拿,賠了錢的也付給我,一切就OK啦,俺得到了四個MM的電話。

          調停者模式:調停者模式包裝了一系列對象相互作用的方式,使得這些對象不必相互明顯作用。從而使他們可以松散偶合。當某些對象之間的作用發生改變時,不會立即影響其他的一些對象之間的作用。保證這些作用可以彼此獨立的變化。調停者模式將多對多的相互作用轉化為一對多的相互作用。調停者模式將對象的行為和協作抽象化,把對象在小尺度的行為上與其他對象的相互作用分開處理。

          18、MEMENTO—同時跟幾個MM聊天時,一定要記清楚剛才跟MM說了些什么話,不然MM發現了會不高興的哦,幸虧我有個備忘錄,剛才與哪個MM說了什么話我都拷貝一份放到備忘錄里面保存,這樣可以隨時察看以前的記錄啦。

          備忘錄模式:備忘錄對象是一個用來存儲另外一個對象內部狀態的快照的對象。備忘錄模式的用意是在不破壞封裝的條件下,將一個對象的狀態捉住,并外部化,存儲起來,從而可以在將來合適的時候把這個對象還原到存儲起來的狀態。

          19、OBSERVER—想知道咱們公司最新MM情報嗎?加入公司的MM情報郵件組就行了,tom負責搜集情報,他發現的新情報不用一個一個通知我們,直接發布給郵件組,我們作為訂閱者(觀察者)就可以及時收到情報啦

          觀察者模式:觀察者模式定義了一種一隊多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態上發生變化時,會通知所有觀察者對象,使他們能夠自動更新自己。

          20、STATE—跟MM交往時,一定要注意她的狀態哦,在不同的狀態時她的行為會有不同,比如你約她今天晚上去看電影,對你沒興趣的MM就會說“有事情啦”,對你不討厭但還沒喜歡上的MM就會說“好啊,不過可以帶上我同事么?”,已經喜歡上你的MM就會說“幾點鐘?看完電影再去泡吧怎么樣?”,當然你看電影過程中表現良好的話,也可以把MM的狀態從不討厭不喜歡變成喜歡哦。

          狀態模式:狀態模式允許一個對象在其內部狀態改變的時候改變行為。這個對象看上去象是改變了它的類一樣。狀態模式把所研究的對象的行為包裝在不同的狀態對象里,每一個狀態對象都屬于一個抽象狀態類的一個子類。狀態模式的意圖是讓一個對象在其內部狀態改變的時候,其行為也隨之改變。狀態模式需要對每一個系統可能取得的狀態創立一個狀態類的子類。當系統的狀態變化時,系統便改變所選的子類。
          21、STRATEGY—跟不同類型的MM約會,要用不同的策略,有的請電影比較好,有的則去吃小吃效果不錯,有的去海邊浪漫最合適,單目的都是為了得到MM的芳心,我的追MM錦囊中有好多Strategy哦。

          策略模式:策略模式針對一組算法,將每一個算法封裝到具有共同接口的獨立的類中,從而使得它們可以相互替換。策略模式使得算法可以在不影響到客戶端的情況下發生變化。策略模式把行為和環境分開。環境類負責維持和查詢行為類,各種算法在具體的策略類中提供。由于算法和環境獨立開來,算法的增減,修改都不會影響到環境和客戶端。

          22、TEMPLATE METHOD——看過《如何說服女生上床》這部經典文章嗎?女生從認識到上床的不變的步驟分為巧遇、打破僵局、展開追求、接吻、前戲、動手、愛撫、進去八大步驟(Template method),但每個步驟針對不同的情況,都有不一樣的做法,這就要看你隨機應變啦(具體實現);

          模板方法模式:模板方法模式準備一個抽象類,將部分邏輯以具體方法以及具體構造子的形式實現,然后聲明一些抽象方法來迫使子類實現剩余的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩余的邏輯有不同的實現。先制定一個頂級邏輯框架,而將邏輯的細節留給具體的子類去實現。

          23、VISITOR—情人節到了,要給每個MM送一束鮮花和一張卡片,可是每個MM送的花都要針對她個人的特點,每張卡片也要根據個人的特點來挑,我一個人哪搞得清楚,還是找花店老板和禮品店老板做一下Visitor,讓花店老板根據MM的特點選一束花,讓禮品店老板也根據每個人特點選一張卡,這樣就輕松多了;

          訪問者模式:訪問者模式的目的是封裝一些施加于某種數據結構元素之上的操作。一旦這些操作需要修改的話,接受這個操作的數據結構可以保持不變。訪問者模式適用于數據結構相對未定的系統,它把數據結構和作用于結構上的操作之間的耦合解脫開,使得操作集合可以相對自由的演化。訪問者模式使得增加新的操作變的很容易,就是增加一個新的訪問者類。訪問者模式將有關的行為集中到一個訪問者對象中,而不是分散到一個個的節點類中。當使用訪問者模式時,要將盡可能多的對象瀏覽邏輯放在訪問者類中,而不是放到它的子類中。訪問者模式可以跨過幾個類的等級結構訪問屬于不同的等級結構的成員類。

          posted @ 2007-07-02 13:19 和田雨 閱讀(229) | 評論 (0)編輯 收藏

          1,前言
          2,摘要
          3,如何使用本文
          4,Google簡介
          5,搜索入門
          6,初階搜索
            6.1,搜索結果要求包含兩個及兩個以上關鍵字
            6.2,搜索結果要求不包含某些特定信息
            6.3,搜索結果至少包含多個關鍵字中的任意一個
          7,雜項語法
            7.1,通配符問題
            7.2,關鍵字的字母大小寫
            7.3,搜索整個短語或者句子
            7.4,搜索引擎忽略的字符以及強制搜索
          8,進階搜索
            8.1,對搜索的網站進行限制
            8.2,查詢某一類文件
            8.3,搜索的關鍵字包含在URL鏈接中
            8.4,搜索的關鍵字包含在網頁標題中
            8.5,搜索的關鍵字包含在網頁“錨”內
          9,其他罕用語法
            9.1,搜索所有鏈接到某個URL地址的網頁
            9.2,查找與某個頁面結構內容相似的頁面
            9.3,從Google服務器上緩存頁面中查詢信息
          10,圖片搜索
          11,目錄檢索
          12,新聞組搜索
          13,Google的其他杰出功能
            13.1,網頁快照
            13.2,集成化的工具條
            13.3,單詞英文解釋
            13.4,網頁翻譯
            13.5,單詞糾錯
            13.6,搜索結果過濾
          14,Google尚未發布的一些新特性和功能
            14.1,對網頁更新日期做出限定
            14.2,新聞搜索
            14.3,分類廣告搜索
            14.4,其它Google的最新發展動態
            14.5,一個有趣的地方
          15,后記

          ——————————————————————————————————

          [B]1,前言[/B]

            我是在2000年上半年知道Google的。在這之前,我搜索英文信息通常用AltaVista,而搜索中文信息則常用Sina。但自使用了Google之后,它便成為我的Favorite Search engine了。這也得感謝新浪網友曹溪,因為當初正是因為他的大力推介,才使我識得了Google。

            記得1996年夏季的時候,當我第一次接觸Internet,便被撲面而來的魔力征服了。那種天涯咫尺的感覺,真是妙不可言。在經歷了瘋狂的WWW沖浪和如癡如醉的BBS沉迷之后,我意識到Internet對我影響至深的還是在于學習方式的變遷。

            如何來描述這種變遷呢?以前的學習,一般需要預先在肚子里存儲下足夠的知識,必要時,就從海量的信息中提取所需的部分。這種學習方式造就了很多“才高八斗,學富五車”的大才子。但是,到了信息領域大大超出“四書五經”的新時期,預先無目的的吞下海量信息的學習方式就有些不合時宜了。比方說,我們到了大型的圖書城,往往有一種不知所措的感覺。舊有的學習方式需要變更以適應這個信息爆炸的年代。目的明確的去學習,即先知道要學什么,然后有目的的去尋找答案,這種方式看上去更加有效率。我不妨把這稱為“即學式”,相應的,舊有的稱為“預學式”。

            不過,“即學式”的實施是有前提的。首先,要求學習者擁有一個包羅萬象的信息庫,以供隨時抽取各種目的信息;其次,是需要一個強勁的信息檢索工具,以便高效率的從信息庫中提取信息。很明顯,Internet可以充當那個海量的信息庫,而搜索引擎,則正是尋找光明之火的絕好工具。

            “公欲善其事,必先利其器”。Internet只有一個,而搜索引擎則有N多個。有搜索高手說,所謂搜索,就是“在正確的地方使用正確的工具和正確的方法尋找正確的內容”。但是,對于普通人而言,掌握諸多搜索引擎的可能性似乎不大。用一兩個相對強勁的具代表性的工具達到絕大多數搜索目的更為人們所迫切希望。不同的時期,涌現出不同的強者。就目前而言,我們非常幸運的有了: *****Google******


          [B]2,摘要[/B]

            本文簡要的介紹了Google的歷史和特點,Google的基本搜索語法和高級搜索語法,Google的特色功能,包括圖片搜索、新聞組搜索和集成工具條等。盡管本文名為“Google搜索從入門到精通”,但事實上,本文只能算是對Google的一個并不十分完全的介紹而已。:)


          3,如何使用本文

            閱讀本文最好具備一些最基本的布爾代數基礎,如“與”、“或”、“非”等。不過,即便你沒有這方面的知識,也不必在意。對那些實例進行練習,你的疑惑就會迎刃而解。對于剛剛接觸網絡搜索的讀者而言,也許你應該從頭到尾的閱讀本文;但對于那些有一定搜索基礎的讀者而言,只需要跳躍著尋找自己所需要的信息就可以了。此外,你也可以參考中文Google大全:http://www.Google.com/intl/zh-CN/about.html,以及搜索幫助:http://www.google.com/intl/zh-CN/help.html,那是官方Google使用手冊以及問題解答中心。


          4,Google簡介

            Google(www.Google.com)是一個搜索引擎,由兩個斯坦福大學博士生Larry Page與Sergey Brin于1998年9月發明,Google Inc. 于1999年創立。2000年7月份,Google替代Inktomi成為Yahoo公司的搜索引擎,同年9月份,Google成為中國網易公司的搜索引擎。98年至今,Google已經獲得30多項業界大獎。到Google的新聞中心(http://www.Google.com/press/index.html),你可以找到關于一切關于Google的歷史和新聞資料。

            Google的成功得益于其強大的功能和獨到的特點:

          Google檢索網頁數量達24億,搜索引擎中排名第一;
          Google支持多達132種語言,包括簡體中文和繁體中文;
          Google網站只提供搜索引擎功能,沒有花里胡哨的累贅;
          Google速度極快,年初時據說有15000多臺服務器,200多條T3級寬帶;
          Google的專利網頁級別技術PageRank能夠提供準確率極高的搜索結果;
          Google智能化的“手氣不錯”功能,提供可能最符合要求的網站;
          Google的“網頁快照”功能,能從Google服務器里直接取出緩存的網頁。
          Google具有獨到的圖片搜索功能;
          Google具有強大的新聞組搜索功能;
          Google具有二進制文件搜索功能(PDF,DOC,SWF等);
          Google還有很多尚在開發階段的令人吃驚的設想和功能。
          等等


          5,搜索入門

            要用Google做搜索,當然首先要進Google網站--www.Google.com;不過,163.com和yahoo.com.cn使用的實際上也是Google搜索引擎,只是對搜索結果進行了編排,而且無法提供一些特色功能,如圖片搜索等。因此,如果你要搜索網頁的話,就直接使用Google.com吧。

            第一次進入Google,它會根據你的操作系統,確定語言界面。需要提醒的是,Google是通過cookie來存儲頁面設定的,所以,如果你的系統禁用cookie,就無法對Google界面進行個人設定了。

            Google的首頁很清爽,LOGO下面,排列了四大功能模塊:網站、圖像、新聞組和目錄服務。默認是網站搜索。現在進行第一次搜索實踐,假定你是個搜索新手,想要了解一下搜索引擎的來龍去脈和搜索技巧。在搜索框內輸入一個關鍵字“搜索引擎”, 選中“搜索中文(簡體)網頁”選項,然后點擊下面的“Google搜索”按鈕(或者直接回車),結果就出來了。 搜索:“搜索引擎”
          結果:已搜索有關搜索引擎的中文(簡體)網頁。 共約有707,000項查詢結果,這是第1-10項 。 搜索用時0.08秒。

            仔細看一下搜索結果的前十項,就會發現絕大部分鏈接是搜索引擎本身,而不是對搜索引擎的或者搜索技巧方面的介紹。

            注意:文章中搜索語法外面的引號僅起引用作用,不能帶入搜索欄內。


          6,初階搜索

            上例是最基本的搜索,即查詢包含單個關鍵字的信息。但是,你可以發現,上例中,單個關鍵字“搜索引擎”,搜索得的信息浩如煙海,而且絕大部分并不符合自己的要求,怎么辦呢?我們需要進一步縮小搜索范圍和結果。

          6.1,搜索結果要求包含兩個及兩個以上關鍵字

            一般搜索引擎需要在多個關鍵字之間加上“ ”,而Google無需用明文的“ ”來表示邏輯“與”操作,只要空格就可以了。現在,我們需要了解一下搜索引擎的歷史,因此期望搜得的網頁上有“搜索引擎”和“歷史”兩個關鍵字。

          示例:搜索所有包含關鍵詞“搜索引擎”和“歷史”的中文網頁
          搜索:“搜索引擎 歷史”
          結果:已搜索有關搜索引擎 歷史的中文(簡體)網頁。 共約有78,600項查詢結果,這是第1-10項 。 搜索用時0.36秒。

            用了兩個關鍵字,查詢結果已經從70多萬項減少到7萬多項。但查看一下搜索結果,發現前列的絕大部分結果還是不符合要求,大部分網頁涉及的“歷史”,并不是我們所需要的“搜索引擎的歷史”。 怎么辦呢?刪除與搜索引擎不相關的“歷史”。我們發現,這部分無用的資訊,總是和“文化”這個詞相關的,另外一些常見詞是“中國歷史”、“世界歷史”、“歷史書籍”等。

          6.2,搜索結果要求不包含某些特定信息

            Google用減號“-”表示邏輯“非”操作。“A –B”表示搜索包含A但沒有B的網頁。

          示例:搜索所有包含“搜索引擎”和“歷史”但不含“文化”、“中國歷史”和“世界歷史”的中文網頁
          搜索:“搜索引擎 歷史 -文化 -中國歷史 -世界歷史”
          結果:已搜索有關搜索引擎 歷史 -文化 -中國歷史 -世界歷史的中文(簡體)網頁。 共約有36,800項查詢結果,這是第1-10項 。 搜索用時0.22秒。

            我們看到,通過去掉不相關信息,搜索結果又減少了將近一半。第一個搜索結果是:

          搜索引擎直通車≡搜索引擎發展歷史
          搜索引擎直通車, ... 搜索引擎專業介紹站點. ...
          www.se-express.com/about/about.htm - 14k - 網頁快照 - 類似網頁

          非常符合搜索要求。另外,第八項搜索結果:

          463搜索王
          本站檢索 整個網站 在此輸入關鍵詞. 你的當前
          位置:首頁 >> Internet搜索手冊 >> 搜索引擎的歷史. ...
          www.cnco.net/search/history.htm - 21k - 網頁快照 - 類似網頁

            也符合搜索要求。但是,10個結果只有兩個符合要求,未免太少了點。不過,在沒有更好的策略之前,不妨先點開一個結果看看。點開se-express.com的這個名為“搜索引擎發展歷史”的網頁,我們發現,搜索引擎的歷史,是與互聯網早期的文件檢索工具“Archie”息息相關的。此外,搜索引擎似乎有個核心程序,叫“蜘蛛”,而最早成型的搜索引擎是“Lycos”,使搜索引擎深入人心的是“Yahoo”。了解了這些信息,我們就可以進一步的讓搜索結果符合要求了。

            注意:這里的“ ”和“-”號,是英文字符,而不是中文字符的“+”和“-”。此外,操作符與作用的關鍵字之間,不能有空格。比如“搜索引擎 - 文化”,搜索引擎將視為關鍵字為“搜索引擎”和“文化”的邏輯“與”操作,中間的“-”被忽略。

          6.3,搜索結果至少包含多個關鍵字中的任意一個。

            Google用大寫的“OR”表示邏輯“或”操作。搜索“A OR B”,意思就是說,搜索的網頁中,要么有A,要么有B,要么同時有A和B。在上例中,我們希望搜索結果中最好含有“archie”、“lycos”、“蜘蛛”等關鍵字中的一個或者幾個,這樣可以進一步的精簡搜索結果。

          示例:搜索如下網頁,要求必須含有“搜索引擎”和“歷史”,沒有“文化”,可以含有以下關鍵字中人任何一個或者多個:“Archie”、“蜘蛛”、“Lycos”、“Yahoo”。
          搜索:“搜索引擎 歷史 archie OR 蜘蛛 OR lycos OR yahoo -文化”
          結果:已搜索有關搜索引擎 歷史 archie OR 蜘蛛 OR lycos OR yahoo -文化的中文(簡體)網頁。 共約有8,400項查詢結果,這是第1-10項 。 搜索用時0.16秒。

            我們看到,搜索結果縮小到8千多項,前20項結果中,大部分都符合搜索要求。如果你想了解一下解搜索引擎的歷史發展,就不妨研究一下現在搜索到的結果吧。 注意:“與”操作必須用大寫的“OR”,而不是小寫的“or”。

            在上面的例子中,我介紹了搜索引擎最基本的語法“與”“非”和“或”,這三種搜索語法Google分別用“ ”(空格)、“-”和“OR”表示。順著上例的思路,你也可以了解到如何縮小搜索范圍,迅速找到目的資訊的一般方法:目標信息一定含有的關鍵字(用“ ”連起來),目標信息不能含有的關鍵字(用“-”去掉),目標信息可能含有的關鍵字(用“OR”連起來)。


          7,雜項語法

          7.1,通配符問題

            很多搜索引擎支持通配符號,如“*”代表一連串字符,“?”代表單個字符等。Google對通配符支持有限。它目前只可以用“*”來替代單個字符,而且包含“*”必須用""引起來。比如,“"以*治國"”,表示搜索第一個為“以”,末兩個為“治國”的四字短語,中間的“*”可以為任何字符。

          7.2,關鍵字的字母大小寫

            Google對英文字符大小寫不敏感,“GOD”和“god”搜索的結果是一樣的。

          7.3,搜索整個短語或者句子

            Google的關鍵字可以是單詞(中間沒有空格),也可以是短語(中間有空格)。但是,用短語做關鍵字,必須加英文引號,否則空格會被當作“與”操作符。

          示例:搜索關于第一次世界大戰的英文信息。
          搜索:“"world war I"”
          結果:已向英特網搜索"world war i". 共約有937,000項查詢結果,這是第1-10項 。 搜索用時0.06秒。

          7.4,搜索引擎忽略的字符以及強制搜索

            Google對一些網路上出現頻率極高的英文單詞,如“i”、“com”、“www”等,以及一些符號如“*”、“.”等,作忽略處理。

          示例:搜索關于www起源的一些歷史資料。
          搜索:“www的歷史 internet”
          結果:以下的字詞因為使用過于頻繁,沒有被列入搜索范圍: www 的. 已搜索有關www的歷史 internet的中文(簡體)網頁。 共約有75,100項查詢結果,這是第1-10項 。 搜索用時0.22秒。

            我們看到,搜索“www的歷史 internet”,但搜索引擎把“www”和“的”都省略了。于是上述搜索只搜索了“歷史”和“internet”。這顯然不符合要求。這里我順便說一點搜索引擎分詞的知識。當我們在搜索“www的歷史”的時候,搜索引擎實際上把這個短語分成三部分,“www”、“的”和“歷史”分別來檢索,這就是搜索引擎的分詞。所以盡管你輸入了連續的“www的歷史”,但搜索引擎還是把這個短語當成三個關鍵字分別檢索。

            如果要對忽略的關鍵字進行強制搜索,則需要在該關鍵字前加上明文的“+”號。
          搜索:“+www +的歷史 internet”
          結果:已搜索有關+www +的歷史 internet的中文(簡體)網頁。 共約有25,000項查詢結果,這是第1-10項 。 搜索用時0.05秒。

            另一個強制搜索的方法是把上述的關鍵字用英文雙引號引起來。在上例“”world war I””中,“I”其實也是忽略詞,但因為被英文雙引號引起來,搜索引擎就強制搜索這一特定短語。

          搜索:“"www的歷史" internet”
          結果:已搜索有關"www的歷史" internet的中文(簡體)網頁。 共約有7項查詢結果,這是第1-6項 。 搜索用時0.26秒。

            我們看到,這一搜索事實上把“www的歷史”作為完整的一個關鍵字。顯然,包含這樣一個特定短語的網頁并不是很多,不過,每一項都很符合要求。

            注意:大部分常用英文符號(如問號,句號,逗號等)無法成為搜索關鍵字,加強制也不行。


          8,進階搜索

            上面已經探討了Google的一些最基礎搜索語法。通常而言,這些簡單的搜索語法已經能解決絕大部分問題了。不過,如果想更迅速更貼切找到需要的信息,你還需要了解更多的東西。

          8.1,對搜索的網站進行限制

            “site”表示搜索結果局限于某個具體網站或者網站頻道,如“www.sina.com.cn”、“edu.sina.com.cn”,或者是某個域名,如“com.cn”、“com”等等。如果是要排除某網站或者域名范圍內的頁面,只需用“-網站/域名”。

          示例:搜索中文教育科研網站(edu.cn)上關于搜索引擎技巧的頁面。
          搜索:“搜索引擎 技巧 site:edu.cn”
          結果:已搜索有關搜索引擎 技巧 site:edu.cn的中文(簡體)網頁。 共約有608項查詢結果,這是第1-10項 。 搜索用時0.05秒。

          示例:上著名IT門戶網站ZDNET和CNET搜索一下關于搜索引擎技巧方面的資訊。
          搜索:“"search engine" tips site:www.zdnet.com OR site:www.cnet.com”
          結果:已在www.zdnet.com內搜索有關"search engine" tips OR site:www.cnet.com的網頁。 共約有1,040項查詢結果,這是第1-10項 。 搜索用時0.09秒。

            注意,在這里Google有個小BUG。“已在www.zdnet.com內搜索…”,其實應該表述成“已在www.zdnet.com和www.cnet.com內搜索…”。

          示例:搜索新浪科技頻道中關于搜索引擎技巧的信息。
          搜索:“搜索引擎 技巧 site:tech.sina.com.cn”
          結果:已在tech.sina.com.cn搜索有關搜索引擎 技巧 的中文(簡體)網頁。 共約有163項查詢結果,這是第1-10項 。 搜索用時0.07秒。

            注意:site后的冒號為英文字符,而且,冒號后不能有空格,否則,“site:”將被作為一個搜索的關鍵字。此外,網站域名不能有“http://”前綴,也不能有任何“/”的目錄后綴;網站頻道則只局限于“頻道名.域名”方式,而不能是“域名/頻道名”方式。

          8.2,在某一類文件中查找信息

            “filetype:”是Google開發的非常強大實用的一個搜索語法。也就是說,Google不僅能搜索一般的文字頁面,還能對某些二進制文檔進行檢索。目前,Google已經能檢索微軟的Office文檔如.xls、.ppt、.doc,.rtf,WordPerfect文檔,Lotus1-2-3文檔,Adobe的.pdf文檔,ShockWave的.swf文檔(Flash動畫)等。其中最實用的文檔搜索是PDF搜索。PDF是ADOBE公司開發的電子文檔格式,現在已經成為互聯網的電子化出版標準。目前Google檢索的PDF文檔大約有2500萬左右,大約占所有索引的二進制文檔數量的80%。PDF文檔通常是一些圖文并茂的綜合性文檔,提供的資訊一般比較集中全面。

          示例:搜索幾個資產負債表的Office文檔。
          搜索:“資產負債表 filetype:doc OR filetype:xls OR filetype:ppt”
          結果:已搜索有關資產負債表 filetype:doc OR filetype:xls OR filetype:ppt的中文(簡體)網頁。 共約有481項查詢結果,這是第1-10項 。 搜索用時0.04秒。

            注意,下載的Office文件可能含有宏病毒,謹慎操作。

          示例:搜索一些關于搜索引擎知識和技巧方面的PDF文檔
          搜索:?quot;search engine" tips OR tutorial filetype:pdf”
          結果:已向英特網搜索"search engine" tips OR tutorial filetype:pdf. 共約有12,600項查詢結果,這是第1-10項 。 搜索用時0.22秒。

            我們來看其中的一個結果:

          [PDF]Search Engines Tips
          文檔類型: PDF/Adobe Acrobat - HTML 版
          ... http://www.google.com/press/zeitgeist.html See what people are searching on at Google.com
          * Search Engine Watch http://searchenginewatch.com/ Some free tips ...
          www.allvertical.com/PromoKits/SearchEngineTips.pdf - 類似網頁

            可以看到,Google用[PDF]來標記這是一個PDF的文檔檢索,另外,它還給出了該PDF文檔的HTML版本,該HTML版保留了文檔的文字內容和結構,但沒有圖片。

          8.3,搜索的關鍵字包含在URL鏈接中

            “inurl”語法返回的網頁鏈接中包含第一個關鍵字,后面的關鍵字則出現在鏈接中或者網頁文檔中。有很多網站把某一類具有嗤?屬性的資源名稱顯示在目錄名稱或者網頁名稱中,比如“MP3”、“GALLARY”等,于是,就可以用INURL語法找到這些相關資源鏈接,然后,用第二個關鍵詞確定是否有某項具體資料。INURL語法和基本搜索語法的最大區別在于,前者通常能提供非常精確的專題資料。 示例:查找MIDI曲“滄海一聲笑”。
          搜索:“inurl:midi “滄海一聲笑””
          結果:已搜索有關inurl:midi "滄海一聲笑"的中文(簡體)網頁。 共約有27項查詢結果,這是第1-10項 。 搜索用時0.34秒。

            注意:“inurl:”后面不能有空格,Google也不對URL符號如“/”進行搜索。例如,Google會把“cgi-bin/phf”中的“/”當成空格處理。

            “allinurl”語法返回的網頁的鏈接中包含所有作用關鍵字。這個查詢的關鍵字只集中于網頁的鏈接字符串。

          示例:查找可能具有PHF安全漏洞的公司網站。通常這些網站的CGI-BIN目錄中含有PHF腳本程序(這個腳本是不安全的),表現在鏈接中就是“域名/cgi-bin/phf”。
          搜索:“allinurl:"cgi-bin" phf +com”
          結果:已向英特網搜索allinurl:"cgi-bin" phf +com. 共約有51項查詢結果,這是第1-10項 。 搜索用時0.11秒。

          8.4,搜索的關鍵字包含在網頁標題中

            “intitle”和“allintitle”的用法類似于上面的inurl和allinurl,只是后者對URL進行查詢,而前者對網頁的標題欄進行查詢。網頁標題,就是HTML標記語言title中之間的部分。網頁設計的一個原則就是要把主頁的關鍵內容用簡潔的語言表示在網頁標題中。因此,只查詢標題欄,通常也可以找到高相關率的專題頁面。 示例:查找日本明星藤原紀香的照片集。
          搜索:“intitle:藤原紀香 "寫真集"”
          結果:已搜索有關intitle:藤原紀香 "寫真集"的中文(簡體)網頁。 共約有315項查詢結果,這是第1-10項 。 搜索用時0.15秒。

          8.5,搜索的關鍵字包含在網頁的“錨”(anchor)鏈點內

            所謂“錨”,就是在同一個網頁中快速切換鏈接點。與URL和TITLE類似,Google提供了兩種對anchor的檢索,“inanchor”和“allincnchor”。對此不作詳述。


          9,其他罕用語法

          9.1,搜索所有鏈接到某個URL地址的網頁

            如果你擁有一個個人網站,估計很想知道有多少人對你的網站作了鏈接。而“link”語法就能讓你迅速達到這個目的。

          示例:搜索所有含指向華軍軟件園“www.newhua.com”鏈接的網頁。
          搜索:“link:www.newhua.com”
          結果:搜索有鏈接到www.newhua.com的網頁 。 共約有920項查詢結果,這是第1-10項 。 搜索用時0.12秒。

            注意:“link”不能與其他語法相混合操作,所以“link:”后面即使有空格,也將被Google忽略。另外還要說明的是,link只列出Google索引鏈接很小一部分,而非全部,所以如果你用Google沒有搜到鏈到你的主頁的鏈接,也不必灰心喪氣。

            除了上述功能,link語法還有其它妙用。一般說來,做友情鏈接的網站都有相似地方。這樣,你可以通過這些友情鏈接,找到一大批具有相似內容的網站。比如說,你是個天文愛好者,你發現某網站非常不錯,那么,可以用link語法查一下與之做鏈接的網站,也許可以找到更多符合你興趣的內容。

          9.2,查找與某個頁面結構內容相似的頁面

            “related”用來搜索結構內容方面相似的網頁。例:搜索所有與中文新浪網主頁相似的頁面(如網易首頁,搜狐首頁,中華網首頁等),“related:wwwsina.com.cn/index.shtml”。我到現在也不明白這個語法有什么作用,如果有誰知道,請不吝指教。預先感謝。:)

          9.3,從Google服務器上緩存頁面中查詢信息

            “cache”用來搜索Google服務器上某頁面的緩存,通常用于查找某些已經被刪除的死鏈接網頁,相當于使用普通搜索結果頁面中的“網頁快照”功能。

            其它罕用語法如info、stock等不一一介紹,有興趣的讀者可以參閱Google大全。


          10,圖片搜索

            Google自稱可以檢索390,000,000張圖片,并稱自己為“互聯網上最好用的圖像搜索工具”。從使用結果來看,Google的圖片搜索的確不錯,但個人以為比AltaVista的還是要差一些,主要體現在檢索圖片數量比不上AV,匹配度比AV的圖片搜索器也差了些。但AltaVista國內用戶無法正常訪問,因此對中國用戶而言,Google的圖片搜索引擎已經是最好的了。

            Google首頁點擊“圖像”鏈接就進入了Google的圖像搜索界面“images.Google.com”。你可以在關鍵字欄位內輸入描述圖像內容的關鍵字,如“britney spears”,就會搜索到大量的小甜甜布蘭妮的圖片。我目前尚不是很清楚圖片的排列標準,不過以觀察來看,似乎圖片文件名完全符合關鍵字的結果排列比較考前,然后才按照普通的頁面搜索時的標準排列。

            Google給出的搜索結果具有一個直觀的縮略圖(THUMBNAIL),以及對該縮略圖的簡單描述,如圖像文件名稱,以及大小等。點擊縮略圖,頁面分成兩禎,上禎是圖像之縮略圖,以及頁面鏈接,而下禎,則是該圖像所處的頁面。屏幕右上角有一個“Remove Frame”的按鈕,可以把框架頁面迅速切換到單禎的結果頁面,非常方便。

            Google圖像搜索目前支持的語法包括基本的搜索語法如“ ”、“-”、“OR”、“site”和 “filetype:”。其中“filetype:”的后綴只能是幾種限定的圖片類似,如JPG,GIF等。

          示例:查找新浪網上本拉登的圖片
          搜索:“拉登 OR 拉丹 site:sina.com.cn”
          結果:搜索有關 拉登 OR 拉丹 site:sina.com.cn 的圖片。 共有6項查詢結果,這是第1-6項。 搜索用時0.36秒。

            這里我想說明一點的是,images.google.com作為專門的圖片搜索引擎,實際上有其特殊的用途。

            舉個例子,互聯網上本拉登的照片成千上萬,但是,它們都是分散的,往往隨機的分布于各種新聞報道中。如果用搜索圖片庫的方式(最容易想到的如“Ben Ladin photo”),來搜索本拉登的照片,顯然是不恰當的,因為很少有人專門為拉登建一個在線相冊。在這個時候,images.google.com就派上用場了。

            但是,如果查找的圖片在網上有很多主題“gallary”,如諸多電影電視明星的照片,則明顯就不適合用images.google.com來查找了。

            images.google.com對于很多報紙雜志的編輯,絕對是一個雪中送炭式的工具。比如要在某個版面上插一張專題圖片,用google的圖片搜索功能幾秒鐘就可以搞定。

            綜上,可以有這樣的一般性結論:如果要搜索的圖片是分散的,則用google圖片搜索;如果要搜索的圖片通常是處于某個圖片集合中的,則不適合用google圖片搜索。


          11,目錄檢索

            如果不想搜索廣泛的網頁,而是想尋找某些專題網站,可以訪問Google的分類目錄“http://directory.Google.com/”,中文目錄是“http://directory.Google.com/Top/World/Chinese_Simplified/”。分類的網站目錄一般由專人負責,分類明確,信息集中。因此讀者應該養成這樣的習慣:首先考慮所需要的信息能否在一個專門主題的網站上找到。不過需要說明的是,用目錄檢索,往往需要用戶對查詢的領域很熟悉。否則,連查詢的內容屬于哪個類目都不知道,目錄瀏覽也就無從談及了。 目前Google使用的分類目錄采用了ODP的內容。“Open Directory Project”是網景公司所主持的一項大型公共網頁目錄。由全世界各地的義務編輯人員來審核挑選網頁,并依照網頁的性質及內容來分門別類。因此,在某一目錄門類中進行搜索往往能有更高的命中率。另外,Google根據其專業的“網頁級別”(PageRank)技術對目錄中登錄的網站進行了排序,可以讓一般的檢索更具高效率。

          示例:查找一下介紹搜索引擎方面的中文網站
          搜索:先進入中文簡體分類目錄,再進入“計算機”目錄,再進入“互聯網絡”子目錄,再進入“搜尋”子目錄。我們看到在“World > Chinese Simplified > 計算機 > 互聯網絡 > 搜尋”下,還有兩個子目錄“分類目錄 (33) 搜索引擎 (10)”,以及6個相關網站。顯然,這些都是我們所需要的信息。

            除了用鼠標層層點入,也可以在目錄中檢索。比如,在上例的“互聯網絡”目錄下,選中“只在互聯網絡中搜索”選項,在搜索欄內填入“搜索引擎”進行搜索。
          結果:在分類Google 網頁目錄項中搜索搜索引擎。 共約有387項查詢結果,這是第11-20項 。 搜索用時0.09秒。

            可以看到,上述查詢結果比普通的檢索更有效,因為在分類“互聯網絡”下進行搜索剔除了很多不相關的諸如新聞之類的無效信息。不過,對于中文用戶而言,現在最大的問題是志愿的中文目錄編輯太少,導致收錄站點太少,因此搜索結果范圍顯得過于狹隘。但愿這個問題能隨著Google以及ODP項目在國內名聲的響亮而能得到改觀。


          12,新聞組搜索

            新聞組有詳盡的分類主題,某些主題還有專人管理和編輯,具有大量的有價值信息。由于新聞組包含的信息實在是海量,因此不利用工具進行檢索是不大可能的。DEJA一直是新聞組搜索引擎中的佼佼者。2001年2月份,Google將DEJA收購并提供了所有DEJA的功能。現在,除了搜索之外,Google還支持新聞組的WEB方式瀏覽和張貼功能。

            進入Google新聞組“http://groups.Google.com/”,你有兩種信息查找方式。一種是一層層的點擊進入特定主題討論組,另一種則是直接搜索。現在,我們進行一個最簡單的搜索試驗,查找一下新聞組中關于山頂洞人的討論信息。

          搜索:“山頂洞人”
          結果:在各群組內搜索 山頂洞人 共約有2,400項查詢結果,這是第1-10項 。 搜索用時0.94秒。 搜索結果默認按照“留言內容”排列,但是你也可以點擊“依照日期”按鈕,讓帖子按照發布日期排列。

            因為新聞組中的帖子實在是多,而且又涉及一些普通搜索所沒有的語法,所以建議使用“高級群組搜尋”進入高級搜索界面。新聞組高級搜索提供留言內容、分類主題、標題、留言者、留言代碼、語言和發布日期作為條件進行搜索。其中作者項指作者發帖所用的唯一識別號電子信箱。


          13,Google的其他杰出功能

          13.1網頁快照

            網頁快照是Google抓下來緩存在服務器上的網頁。它有三個作用:

          第一, 如果原地址打開很慢,那么可以直接查看Google緩存頁面,因為Google服務器速度極快。

          第二, 如果原鏈接已經死掉或者因為網絡的原因暫時鏈接不通,那么可以通過Google快照看到該頁面信息。當然,快照內容不是該頁最新頁面。

          第三, 如果打開的頁面信息量巨大,一下子找不到關鍵詞所在位置,那么可以通過Google快照,因為快照中Google用黃色表明關鍵字位置。

          13.2,集成化的工具條

            為了方便搜索者,Google提供了工具條,集成于瀏覽器中,用戶無需打開Google主頁就可以在工具條內輸入關鍵字進行搜索。此外,工具條還提供了其他許多功能,如顯示頁面PageRank等。最方便的一點在于用戶可以快捷的在Google主頁、目錄服務、新聞組搜索、高級搜索和搜索設定之間切換。欲安裝Google的工具條,可以訪問“http://toolbar.Google.com/”,按頁面提示可以自動下載并安裝。不過,Google工具條目前只支持IE5.0以上版本。

            對于經常進行網絡搜索者而言,Google工具條實在是必備的東西!!

          13.3,單詞英文解釋

            寫英文文章的時候,最頭疼的事情就是對某個英文單詞的用法不確定。現在有了Google,一切就迎刃而解了!無論你是想查找某個生詞的意思還是想了解某個單詞的用法,均可使用在線詞典。

            進入英文Google,輸入你要查的單詞。舉個例子,我想查一下suggest的用法。結果如下:“Searched the web for suggest. Results 1 - 10 of about 8,000,000. Search took 0.08 seconds. ”注意看上面句子中,單詞suggest下出現了一個橫線,點擊這個鏈接,就跳轉到另外一個網站“http://www.dictionary.com/”,Google已經把單詞提交給該網站的查詢腳本。看看這個網站所提供的詳盡解釋吧。:)

          13.4,網頁翻譯

            你懂英文,但是你不見得就懂德文、法文、拉丁文。如果搜索出來的頁面是這些語言怎么辦?呵呵,Google提供了網頁翻譯功能!!雖然目前只支持有限的拉丁語、法語、西班牙語、德語和葡萄牙文,但是我不得不承認,這是個杰出功能。

            試著做以下搜索:“big bang site:fr”。這個表示查找關于宇宙大爆炸的法文網頁。看第一條結果:

          The Big Bang Website - [ Translate this page ]
          ... A propos de Big Bang. Le dernier numéro en date. Les anciens numéros. Autres
          activités. Concerts progressifs en France. Emissions de radio. Liens.
          perso.club-internet.fr/calyx/bigbang/ - 3k - Cached - Similar pages

            有點暈。沒關系,點擊“Translate this page”按鈕。再看結果,嗯,大致能看明白,這原來是個叫“big bang”的樂隊的網站,與大爆炸無關...

            機器翻譯是一個很前沿的人工智能課題,想指望翻譯出來的結果跟專門用英語撰寫的內容是不可能的。但西文間的互相轉譯比中英文機譯強得多得多了。至少能看明白。

          13.5,單詞糾錯

            筆者記憶力很差,英文單詞經常拼寫錯誤。但Google有糾錯功能。比如在寫上文的時候,我要用到英文單詞“tutorial”,我只是依稀記得好像是“tatorial”的樣子,但不肯定,于是用Google查了一下,它馬上提醒:“您要找的會不會是: tutorial ”,呵呵,正是這個單詞。

          13.6,繁簡轉換

            對中文用戶而言,常希望能同時檢索繁體和簡體信息。Google能做到這一點。Google默認使用繁簡自動轉換功能,因此你輸入的簡體關鍵字也將被轉換成繁體做檢索。這樣省了不少力氣。當然,如果你不希望這樣的話,也可以在“使用偏好”中把這個選項關掉。

          13.7,搜索結果過濾

            網絡上的成人內容浩如煙海,而且很多站點具有欺騙或者其他不良企圖,瀏覽者很容易掉入其中的陷阱。為此,Google新設立了成人內容過濾功能,見Google的設置頁面,http://www.Google.com/preferences,最底下有一個選項SafeSearch Filtering。不過,中文狀態下的Google尚沒有這個功能。


          14,Google尚未發布的一些新特性和功能

          14.1,對網頁更新日期做出限定“daterange:”

            評價一個搜索引擎的好壞,更新頻率是一個很關鍵因素。通常情況下,我們總希望能找到最新的網頁。Google已經開發了對更新日期做限定的搜索語法,但目前還未公布。而且比較麻煩的是,Google現在支持的日期格式為julian(凱撒日)格式,把通用日期數值切換成julian格式需要借助第三方網站:http://www.tesre.bo.cnr.it/~mauro/JD/。不過,在下面這個自稱是“Google終極搜索界面”的網頁上,你已經可以利用Google的這項新特性了,它自動提供日期轉換功能。

          Google Ultimate Interface:http://www.faganfinder.com/google.html

            Google為什么要這樣做呢?也許是在測試階段,不想讓太多人使用吧。:)

          14.2,新聞搜索“http://news.google.com/”

            Google的新聞搜索尚在B測試階段,但使用起來已經非常不錯了。新聞首頁按頭條新聞,各國新聞,以及不同領域做了分類。你可以通過Google搜索各大門戶和新聞網站的新聞,簡單、快捷、方便。遺憾的是,目前Google新聞只檢索英文信息。

          14.3,分類廣告搜索“http://catalogs.google.com/”

            這也在B測試階段。主要是對電子分類廣告做檢索。廣告頁為JPG圖片格式。

          14.4,其它Google的最新發展動態

            想了解Google公司的工程師們都在忙些什么嗎?去看一下Google實驗室(http://labs.google.com/)吧。Google的最新設想都在這個地方向訪問者展現出來。現在處于發展和試驗階段的新功能有:術語查詢、語音查詢、鍵盤查詢等等。

            網絡工程師和程序員可以看看這個地方:http://www.google.com/apis/,我想可以讓你喜出望外的。

          14.5,一個有趣的地方

            想看看世界各國網民都用Google搜索什么信息么?到http://www.google.com/press/zeitgeist.html看一下就知道了。從這些資訊中,你大致可以了解到世界熱點和流行時尚走向。:)


          15,后記

            這個文章4.0版本與3.0版本相比,變更很大,主要把一些與Google無關的東西刪除了,另外隨Google的變化作了一些修正,并增加了一些Google尚未發布的新功能。關于搜索技巧和搜索實例,是各個搜索引擎共通的東西,是搜索者長期的經驗積累,要寫出來,是件工程很浩大的事情,因此在這個小文章中我就不獻丑了。

            隨著時間的推移,我發現搜索已經成為網絡生活的一部分。工作需要搜索技術文檔、客戶信息;購物需要搜索商品信息和指南;娛樂需要搜索相關背景資料和圖片。搜索已經變得無處不在,而Google則相應的成了工作和生活中的一個必備工具。套用雅虎的一句廣告詞,我們也許應該這樣說:“今天你Google了嗎?”
          posted @ 2007-07-02 13:17 和田雨 閱讀(5616) | 評論 (0)編輯 收藏

          僅列出標題
          共9頁: 上一頁 1 2 3 4 5 6 7 8 9 下一頁 
          主站蜘蛛池模板: 海南省| 新源县| 永丰县| 成安县| 罗源县| 澄江县| 平远县| 始兴县| 长丰县| 凌云县| 香港 | 永登县| 太仓市| 仁怀市| 苏尼特左旗| 英吉沙县| 招远市| 潼关县| 吴桥县| 辽阳县| 闵行区| 清徐县| 嘉善县| 铁力市| 乌兰浩特市| 太谷县| 平乡县| 同心县| 赤壁市| 平湖市| 金塔县| 诸城市| 喀喇| 平江县| 阿鲁科尔沁旗| 澎湖县| 连州市| 高碑店市| 庆云县| 达孜县| 北安市|