<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    konhon

    忘掉過去,展望未來。找回自我,超越自我。
    逃避不一定躲的過, 面對不一定最難過, 孤單不一定不快樂, 得到不一定能長久, 失去不一定不再擁有, 可能因為某個理由而傷心難過, 但我卻能找個理由讓自己快樂.

    Google

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      203 Posts :: 0 Stories :: 61 Comments :: 0 Trackbacks

    #

         摘要: 以下問題是這一期間回答waterlily 關于java的一些整理,發(fā)現對大家都很有作用,現在將這些詳細講解的程序單獨列出來供大家參考,學習,討論 ------------------------------------------------------------ 1.使用jdbc連接數據庫--通過jdbc連接數據庫,將SQL語句運行結果打印到控制臺 package?Connect...  閱讀全文
    posted @ 2006-03-24 02:39 konhon 優(yōu)華 閱讀(647) | 評論 (0)編輯 收藏

    為什么GenericServlet在init(ServletConfig config)基礎上增加了一個init()方法? 
     
      init()方法被GenericServlet.init(ServletConfig config)方法調用。
      
      init()方法方便了開發(fā)人員定制Servlet的初始化,而無須去維護ServletConfig對象的存儲工作。
      
      重寫GenericServlet.init(ServletConfig config)必須要顯示的調用super.init(config)方法。
      
      ServletContext.getContext(java.lang.String uripath)的作用是什么?
      
      返回同一Server中指定的path對應的ServletContext對象,通過該對象可以實現與Server中的其他Context打交道。
      
      uripath必須是以"/"開始(該路徑的含義是相對于整個Servlet文檔的根路徑,而不是當前ServletContext的根路徑)。
      
      Servlet生命周期是什么?
      
      一般的Servlet(GenericServlet,即與協議無關的Servlet)的生命周期:init() --> GenericServlet.service(ServletRequest req, ServletResponse res) --> destroy.
      
      HttpServlet的生命周期: init() --> GenericServlet.service(ServletRequest req, ServletResponse res)---> service(HttpServletRequest req, HttpServletResponse resp) --> doXXXX()-->destroy.
      
      有沒有必要重寫GenericServlet.service()方法?
      
      對于HttpServlet來說沒有必要。只需要重寫它的doXXXX()方法就可以了。HttpServlet中service()方法會自動的根據用戶請求類型把請求轉發(fā)給相應的doXXXX()方法(例如doGet()方法)。
      
      ServletRequest.getReader()和ServletRequest.getInputStream()如何使用?
      
      注意兩個方法不能同時使用。
      
      ServletRequest.getRealPath(String path)方法已經不推薦使用。
      
      請使用ServletContext.getRealPath(String path)方法。
      
      ServletResponse缺省的字符集(charset)是什么?

      ServletResponse缺省的字符集(charset)是ISO-8859-1,可以通過setContentType(java.lang.String)方法改變新的字符集。
      
      例如:setContentType("text/html; charset=Shift_JIS").
      
      關于字符集信息,可以瀏覽RFC 2045
      
      HttpServletRequest.getRequestURI()和HttpServletRequest.getRequestURL()區(qū)別是什么? 
     
      request.getRequestURI() 返回值類似:/xuejava/requestdemo.jsp
      
      request.getRequestURL() 返回值類似:http://localhost:8080/xuejava/requestdemo.jsp
      
      HttpServletRequest.encodeURL()和HttpServletRequest.encodeRedirectURL(()區(qū)別是什么?為什么要有兩個不同的方法呢?
      
      當用URL-rewriting方式來管理Session的時候,需要用到以上的兩個方法。
      
      兩個方法的不同點是:兩個方法確定是否需要包含session ID的邏輯不同。
      
      在調用HttpServletResponse.sendRedirect前,應該先調用encodeRedirectURL()方法,否則可能會丟失Sesssion信息。 ...
      
      如何使你的Servlet或者JSP實現Single Thread Model?  

      對于Servlet實現javax.single.SingleThreadModel接口。
      
      對于JSP,在Page Directive中寫如下的語句<%@ page isThreadSafe="false" %>
      
      JSP Tag 和 JSP XML-based Tag
      
      ...
      
      如何把某一個JSP Page定義成為Error Page?為什么要這樣做?
      
      實現方法: <%@ page isErrorPage="true" %>
      
      為什么? 因為需要獲取Exception 對象(缺省情況下,在JSP Page中是不能直接使用“隱含對象” exception的)。
      
      JSP Page的執(zhí)行順序是如何的?
      
      JSP Page的執(zhí)行順序如下:
      
      JSP Page Translation. JSP Page --> Servlet source code.
      JSP Page Compilation. Servlet source code --> Servlet class.
      Load Class(First time or the server restarted)
      
      Create instance(可能會很多次,如果JSP Page中聲明了<%@ page isThreadSafe="false" %>)
      
      Call jspInit method(一般的JSP Page都沒有重寫這個方法,重寫需要在聲明語句段中)。
      
      Call _jspService method(類似與一般HttpServlet的doGet和doPost方法,但是可以同時用來處理Post和Getq請求)。
      
      Call jspDestroy method(Server在卸載Servet的時候,例如當Servlet很久沒有使用的情況)。
      
      JSP Page中有哪些隱含對象(Implicity Object)?各自的類型和作用是什么?
      
      request --
      reponse --
      session --
      application --
      out --
      page --
      pagecontext --
      exception -- 只有在當前JSP Page為Error Page的時候才有效。
      config --
      
      <jsp:include page="/foo/foo.jsp" %> 和 <@ include file="/foo/foo.jsp" %>的區(qū)別是什么?
      
      <jsp:include ... -- request time.
      <@ include ... -- Page translation time.
      
      Servlets/JSP Container(Engine)有幾種運行方式?
      
      Standalone
      Tomcat standalone mode
      In-process
      Tomcat running inside Apache Web Server.
      Out-of-process
      Apache + mod_jk + Tomcat
      
      Servlet,Servlet開發(fā)人員,Servlet API, Servlet Container的關系是什么?
      
      Servlet,Servlet開發(fā)人員 --->Servlet API --> Servlet Container
      The parts of an HTTP message
      
      Message part Description
      The initial line: Specifies the purpose of the request or response message
      例子:GET /reports/sales/index.html HTTP/1.0
      The header section:Specifies the meta-information, such as size, type, and encoding,
      about the content of the message
      A blank line:
      An optional message body: The main content of the request or response message
      
      下面是一個Response的例子:
      
      HTTP/1.0 200 OK
      Date: Tue, 01 Dec 2001 23:59:59 GMT
      Content-Type: text/html
      Content-Length: 52
      
      <html>
      <body>
      <h1>Hello, John!</h1>
      </body>
      </html>
      
      HTTP規(guī)范中定義了哪些方法?各自有什么用途?
      
      GET
      HEAD
      POST
      從 Http 1.1規(guī)范開始,增加了以下的方法:
      
      PUT
      OPTIONS
      TRACE
      DELETE
      CONNECT
      
      ServetRequest中為什么要定義:getContentType(),getContentLength()方法。
      
      根據HTTP協議規(guī)范,Request 和 Response一樣也有這些必不可少的內容!
      
      所以需要首先了解 HTTP Message的概念和其內容的格式,這些東西對于Request和Reponse是一樣的。
      
      對于GET方式發(fā)送的請求,其內容類型為:null
      
      對于POST方式發(fā)送的請求,其內容類型為:application/x-www-form-urlencoded
      
      POST方式發(fā)送請求的內容類似于:username=xuejava.
      
      RequestDispatcher.forward()和HttpServletResponse.sendRedirect()的區(qū)別是什么?
      
      RequestDispatcher.forward()是在服務器端運行;HttpServletResponse.sendRedirect()是通過向客戶瀏覽器發(fā)送命令來完成。
      
      所以RequestDispatcher.forward()對于瀏覽器來說是“透明的”;而HttpServletResponse.sendRedirect()則不是。
      
      另外,還要注意RequestDispatcher.forward()在調用的時候Response不能已經Commit了(Response.isCommitted())。
      
      ServletContext.getRequestDispatcher(String url)和ServletRequest.getRequestDispatcher(String url)的區(qū)別是什么?為什么?
      
      ServletContext.getRequestDispatcher(String url)中的url只能使用絕對路徑;而ServletRequest.getRequestDispatcher(String url)中的url可以使用相對路徑。
      
      因為ServletRequest具有相對路徑的概念;而ServletContext對象無次概念。
      
      如何把請求轉移到另外一個Web App中的某個地址?
      
      ServletContext.getRequestDispatcher(String url)和ServletRequest.getRequestDispatcher(String url)只能把請求轉移到同一個Web App中的地址。
      
      如果需要把請求轉移到另外一個Web App中的某個地址,可以按下面的做法:
      
      1. 獲得另外一個Web App的ServletConext對象(currentServletContext.getContext(uripath)).
      
      2. 調用ServletContext.getRequestDispatcher(String url)方法。
    posted @ 2006-03-23 21:53 konhon 優(yōu)華 閱讀(446) | 評論 (0)編輯 收藏

    一、術語session
    在我的經驗里,session這個詞被濫用的程度大概僅次于transaction,更加有趣的是transaction與session在某些語境下的含義是相同的。

    session,中文經常翻譯為會話,其本來的含義是指有始有終的一系列動作/消息,比如打電話時從拿起電話撥號到掛斷電話這中間的一系列過程可以稱之為一個 session。有時候我們可以看到這樣的話“在一個瀏覽器會話期間,...”,這里的會話一詞用的就是其本義,是指從一個瀏覽器窗口打開到關閉這個期間 ①。最混亂的是“用戶(客戶端)在一次會話期間”這樣一句話,它可能指用戶的一系列動作(一般情況下是同某個具體目的相關的一系列動作,比如從登錄到選購商品到結賬登出這樣一個網上購物的過程,有時候也被稱為一個transaction),然而有時候也可能僅僅是指一次連接,也有可能是指含義①,其中的差別只能靠上下文來推斷②。

    然而當session一詞與網絡協議相關聯時,它又往往隱含了“面向連接”和/或“保持狀態(tài)”這樣兩個含義, “面向連接”指的是在通信雙方在通信之前要先建立一個通信的渠道,比如打電話,直到對方接了電話通信才能開始,與此相對的是寫信,在你把信發(fā)出去的時候你并不能確認對方的地址是否正確,通信渠道不一定能建立,但對發(fā)信人來說,通信已經開始了。“保持狀態(tài)”則是指通信的一方能夠把一系列的消息關聯起來,使得消息之間可以互相依賴,比如一個服務員能夠認出再次光臨的老顧客并且記得上次這個顧客還欠店里一塊錢。這一類的例子有“一個TCP session”或者 “一個POP3 session”③。

    而到了web服務器蓬勃發(fā)展的時代,session在web開發(fā)語境下的語義又有了新的擴展,它的含義是指一類用來在客戶端與服務器之間保持狀態(tài)的解決方案④。有時候session也用來指這種解決方案的存儲結構,如“把xxx保存在session 里”⑤。由于各種用于web開發(fā)的語言在一定程度上都提供了對這種解決方案的支持,所以在某種特定語言的語境下,session也被用來指代該語言的解決方案,比如經常把Java里提供的javax.servlet.http.HttpSession簡稱為session⑥。

    鑒于這種混亂已不可改變,本文中session一詞的運用也會根據上下文有不同的含義,請大家注意分辨。
    在本文中,使用中文“瀏覽器會話期間”來表達含義①,使用“session機制”來表達含義④,使用“session”表達含義⑤,使用具體的“HttpSession”來表達含義⑥

    二、HTTP協議與狀態(tài)保持
    HTTP 協議本身是無狀態(tài)的,這與HTTP協議本來的目的是相符的,客戶端只需要簡單的向服務器請求下載某些文件,無論是客戶端還是服務器都沒有必要紀錄彼此過去的行為,每一次請求之間都是獨立的,好比一個顧客和一個自動售貨機或者一個普通的(非會員制)大賣場之間的關系一樣。

    然而聰明(或者貪心?)的人們很快發(fā)現如果能夠提供一些按需生成的動態(tài)信息會使web變得更加有用,就像給有線電視加上點播功能一樣。這種需求一方面迫使HTML逐步添加了表單、腳本、DOM等客戶端行為,另一方面在服務器端則出現了CGI規(guī)范以響應客戶端的動態(tài)請求,作為傳輸載體的HTTP協議也添加了文件上載、 cookie這些特性。其中cookie的作用就是為了解決HTTP協議無狀態(tài)的缺陷所作出的努力。至于后來出現的session機制則是又一種在客戶端與服務器之間保持狀態(tài)的解決方案。

    讓我們用幾個例子來描述一下cookie和session機制之間的區(qū)別與聯系。筆者曾經常去的一家咖啡店有喝5杯咖啡免費贈一杯咖啡的優(yōu)惠,然而一次性消費5杯咖啡的機會微乎其微,這時就需要某種方式來紀錄某位顧客的消費數量。想象一下其實也無外乎下面的幾種方案:
    1、該店的店員很厲害,能記住每位顧客的消費數量,只要顧客一走進咖啡店,店員就知道該怎么對待了。這種做法就是協議本身支持狀態(tài)。
    2、發(fā)給顧客一張卡片,上面記錄著消費的數量,一般還有個有效期限。每次消費時,如果顧客出示這張卡片,則此次消費就會與以前或以后的消費相聯系起來。這種做法就是在客戶端保持狀態(tài)。
    3、發(fā)給顧客一張會員卡,除了卡號之外什么信息也不紀錄,每次消費時,如果顧客出示該卡片,則店員在店里的紀錄本上找到這個卡號對應的紀錄添加一些消費信息。這種做法就是在服務器端保持狀態(tài)。

    由于HTTP協議是無狀態(tài)的,而出于種種考慮也不希望使之成為有狀態(tài)的,因此,后面兩種方案就成為現實的選擇。具體來說cookie機制采用的是在客戶端保持狀態(tài)的方案,而session機制采用的是在服務器端保持狀態(tài)的方案。同時我們也看到,由于采用服務器端保持狀態(tài)的方案在客戶端也需要保存一個標識,所以session機制可能需要借助于cookie機制來達到保存標識的目的,但實際上它還有其他選擇。

    三、理解cookie機制
    cookie機制的基本原理就如上面的例子一樣簡單,但是還有幾個問題需要解決:“會員卡”如何分發(fā);“會員卡”的內容;以及客戶如何使用“會員卡”。

    正統(tǒng)的cookie分發(fā)是通過擴展HTTP協議來實現的,服務器通過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie。然而純粹的客戶端腳本如JavaScript或者VBScript也可以生成cookie。

    而cookie 的使用是由瀏覽器按照一定的原則在后臺自動發(fā)送給服務器的。瀏覽器檢查所有存儲的cookie,如果某個cookie所聲明的作用范圍大于等于將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上發(fā)送給服務器。意思是麥當勞的會員卡只能在麥當勞的店里出示,如果某家分店還發(fā)行了自己的會員卡,那么進這家店的時候除了要出示麥當勞的會員卡,還要出示這家店的會員卡。

    cookie的內容主要包括:名字,值,過期時間,路徑和域。
    其中域可以指定某一個域比如.google.com,相當于總店招牌,比如寶潔公司,也可以指定一個域下的具體某臺機器比如www.google.com或者froogle.google.com,可以用飄柔來做比。
    路徑就是跟在域名后面的URL路徑,比如/或者/foo等等,可以用某飄柔專柜做比。
    路徑與域合在一起就構成了cookie的作用范圍。
    如果不設置過期時間,則表示這個cookie的生命期為瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了。這種生命期為瀏覽器會話期的 cookie被稱為會話cookie。會話cookie一般不存儲在硬盤上而是保存在內存里,當然這種行為并不是規(guī)范規(guī)定的。如果設置了過期時間,瀏覽器就會把cookie保存到硬盤上,關閉后再次打開瀏覽器,這些cookie仍然有效直到超過設定的過期時間。

    存儲在硬盤上的cookie 可以在不同的瀏覽器進程間共享,比如兩個IE窗口。而對于保存在內存里的cookie,不同的瀏覽器有不同的處理方式。對于IE,在一個打開的窗口上按 Ctrl-N(或者從文件菜單)打開的窗口可以與原窗口共享,而使用其他方式新開的IE進程則不能共享已經打開的窗口的內存cookie;對于 Mozilla Firefox0.8,所有的進程和標簽頁都可以共享同樣的cookie。一般來說是用javascript的window.open打開的窗口會與原窗口共享內存cookie。瀏覽器對于會話cookie的這種只認cookie不認人的處理方式經常給采用session機制的web應用程序開發(fā)者造成很大的困擾。

    下面就是一個goolge設置cookie的響應頭的例子
    HTTP/1.1 302 Found
    Location: http://www.google.com/intl/zh-CN/
    Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
    Content-Type: text/html



    這是使用HTTPLook這個HTTP Sniffer軟件來俘獲的HTTP通訊紀錄的一部分


    瀏覽器在再次訪問goolge的資源時自動向外發(fā)送cookie


    用Firefox可以很容易的觀察現有的cookie的值
    使用HTTPLook配合Firefox可以很容易的理解cookie的工作原理。


    IE也可以設置在接受cookie前詢問

    四、理解session機制

    session機制是一種服務器端的機制,服務器使用一種類似于散列表的結構(也可能就是使用散列表)來保存信息。

    當程序需要為某個客戶端的請求創(chuàng)建一個session的時候,服務器首先檢查這個客戶端的請求里是否已包含了一個session標識 - 稱為 session id,如果已包含一個session id則說明以前已經為此客戶端創(chuàng)建過session,服務器就按照session id把這個 session檢索出來使用(如果檢索不到,可能會新建一個),如果客戶端請求不包含session id,則為此客戶端創(chuàng)建一個session并且生成一個與此session相關聯的session id,session id的值應該是一個既不會重復,又不容易被找到規(guī)律以仿造的字符串,這個 session id將被在本次響應中返回給客戶端保存。

    保存這個session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動的按照規(guī)則把這個標識發(fā)揮給服務器。一般這個cookie的名字都是類似于SEEESIONID,而。比如weblogic對于web應用程序生成的cookie,JSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是 JSESSIONID。

    由于cookie可以被人為的禁止,必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞回服務器。經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的后面,附加方式也有兩種,一種是作為URL路徑的附加信息,表現形式為http://...../xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
    另一種是作為查詢字符串附加在URL后面,表現形式為http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
    這兩種方式對于用戶來說是沒有區(qū)別的,只是服務器在解析的時候處理的方式不同,采用第一種方式也有利于把session id的信息和正常程序參數區(qū)分開來。
    為了在整個交互過程中始終保持狀態(tài),就必須在每個客戶端可能請求的路徑后面都包含這個session id。

    另一種技術叫做表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時能夠把session id傳遞回服務器。比如下面的表單
    <form name="testform" action="/xxx">
    <input type="text">
    </form>


    在被傳遞給客戶端之前將被改寫成
    <form name="testform" action="/xxx">
    <input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
    <input type="text">
    </form>


    這種技術現在已較少應用,筆者接觸過的很古老的iPlanet6(SunONE應用服務器的前身)就使用了這種技術。
    實際上這種技術可以簡單的用對action應用URL重寫來代替。

    在談論session機制的時候,常常聽到這樣一種誤解“只要關閉瀏覽器,session就消失了”。其實可以想象一下會員卡的例子,除非顧客主動對店家提出銷卡,否則店家絕對不會輕易刪除顧客的資料。對session來說也是一樣的,除非程序通知服務器刪除一個session,否則服務器會一直保留,程序一般都是在用戶做log off的時候發(fā)個指令去刪除session。然而瀏覽器從來不會主動在關閉之前通知服務器它將要關閉,因此服務器根本不會有機會知道瀏覽器已經關閉,之所以會有這種錯覺,是大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器后這個 session id就消失了,再次連接服務器時也就無法找到原來的session。如果服務器設置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發(fā)出的HTTP請求頭,把原來的session id發(fā)送給服務器,則再次打開瀏覽器仍然能夠找到原來的session。

    恰恰是由于關閉瀏覽器不會導致session被刪除,迫使服務器為seesion設置了一個失效時間,當距離客戶端上一次使用session的時間超過這個失效時間時,服務器就可以認為客戶端已經停止了活動,才會把session刪除以節(jié)省存儲空間。

    五、理解javax.servlet.http.HttpSession
    HttpSession是Java平臺對session機制的實現規(guī)范,因為它僅僅是個接口,具體到每個web應用服務器的提供商,除了對規(guī)范支持之外,仍然會有一些規(guī)范里沒有規(guī)定的細微差異。這里我們以BEA的Weblogic Server8.1作為例子來演示。

    首先,Weblogic Server提供了一系列的參數來控制它的HttpSession的實現,包括使用cookie的開關選項,使用URL重寫的開關選項,session持久化的設置,session失效時間的設置,以及針對cookie的各種設置,比如設置cookie的名字、路徑、域, cookie的生存時間等。

    一般情況下,session都是存儲在內存里,當服務器進程被停止或者重啟的時候,內存里的session也會被清空,如果設置了session的持久化特性,服務器就會把session保存到硬盤上,當服務器進程重新啟動或這些信息將能夠被再次使用, Weblogic Server支持的持久性方式包括文件、數據庫、客戶端cookie保存和復制。

    復制嚴格說來不算持久化保存,因為session實際上還是保存在內存里,不過同樣的信息被復制到各個cluster內的服務器進程中,這樣即使某個服務器進程停止工作也仍然可以從其他進程中取得session。

    cookie生存時間的設置則會影響瀏覽器生成的cookie是否是一個會話cookie。默認是使用會話cookie。有興趣的可以用它來試驗我們在第四節(jié)里提到的那個誤解。

    cookie的路徑對于web應用程序來說是一個非常重要的選項,Weblogic Server對這個選項的默認處理方式使得它與其他服務器有明顯的區(qū)別。后面我們會專題討論。

    關于session的設置參考[5] http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869

    六、HttpSession常見問題
    (在本小節(jié)中session的含義為⑤和⑥的混合)

    1、session在何時被創(chuàng)建
    一個常見的誤解是以為session在有客戶端訪問時就被創(chuàng)建,然而事實是直到某server端程序調用 HttpServletRequest.getSession(true)這樣的語句時才被創(chuàng)建,注意如果JSP沒有顯示的使用 <% @page session="false"%> 關閉session,則JSP文件在編譯成Servlet時將會自動加上這樣一條語句 HttpSession session = HttpServletRequest.getSession(true);這也是JSP中隱含的 session對象的來歷。

    由于session會消耗內存資源,因此,如果不打算使用session,應該在所有的JSP中關閉它。

    2、session何時被刪除
    綜合前面的討論,session在下列情況下被刪除a.程序調用HttpSession.invalidate();或b.距離上一次收到客戶端發(fā)送的session id時間間隔超過了session的超時設置;或c.服務器進程被停止(非持久session)

    3、如何做到在瀏覽器關閉時刪除session
    嚴格的講,做不到這一點。可以做一點努力的辦法是在所有的客戶端頁面里使用javascript代碼window.oncolose來監(jiān)視瀏覽器的關閉動作,然后向服務器發(fā)送一個請求來刪除session。但是對于瀏覽器崩潰或者強行殺死進程這些非常規(guī)手段仍然無能為力。

    4、有個HttpSessionListener是怎么回事
    你可以創(chuàng)建這樣的listener去監(jiān)控session的創(chuàng)建和銷毀事件,使得在發(fā)生這樣的事件時你可以做一些相應的工作。注意是session的創(chuàng)建和銷毀動作觸發(fā)listener,而不是相反。類似的與HttpSession有關的listener還有 HttpSessionBindingListener,HttpSessionActivationListener和 HttpSessionAttributeListener。

    5、存放在session中的對象必須是可序列化的嗎
    不是必需的。要求對象可序列化只是為了session能夠在集群中被復制或者能夠持久保存或者在必要時server能夠暫時把session交換出內存。在 Weblogic Server的session中放置一個不可序列化的對象在控制臺上會收到一個警告。我所用過的某個iPlanet版本如果 session中有不可序列化的對象,在session銷毀時會有一個Exception,很奇怪。

    6、如何才能正確的應付客戶端禁止cookie的可能性
    對所有的URL使用URL重寫,包括超鏈接,form的action,和重定向的URL,具體做法參見[6]
    http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770

    7、開兩個瀏覽器窗口訪問應用程序會使用同一個session還是不同的session
    參見第三小節(jié)對cookie的討論,對session來說是只認id不認人,因此不同的瀏覽器,不同的窗口打開方式以及不同的cookie存儲方式都會對這個問題的答案有影響。

    8、如何防止用戶打開兩個瀏覽器窗口操作導致的session混亂
    這個問題與防止表單多次提交是類似的,可以通過設置客戶端的令牌來解決。就是在服務器每次生成一個不同的id返回給客戶端,同時保存在session里,客戶端提交表單時必須把這個id也返回服務器,程序首先比較返回的id與保存在session里的值是否一致,如果不一致則說明本次操作已經被提交過了。可以參看《J2EE核心模式》關于表示層模式的部分。需要注意的是對于使用javascript window.open打開的窗口,一般不設置這個id,或者使用單獨的id,以防主窗口無法操作,建議不要再window.open打開的窗口里做修改操作,這樣就可以不用設置。

    9、為什么在Weblogic Server中改變session的值后要重新調用一次session.setValue
    做這個動作主要是為了在集群環(huán)境中提示Weblogic Server session中的值發(fā)生了改變,需要向其他服務器進程復制新的session值。

    10、為什么session不見了
    排除session正常失效的因素之外,服務器本身的可能性應該是微乎其微的,雖然筆者在iPlanet6SP1加若干補丁的Solaris版本上倒也遇到過;瀏覽器插件的可能性次之,筆者也遇到過3721插件造成的問題;理論上防火墻或者代理服務器在cookie處理上也有可能會出現問題。
    出現這一問題的大部分原因都是程序的錯誤,最常見的就是在一個應用程序中去訪問另外一個應用程序。我們在下一節(jié)討論這個問題。

    七、跨應用程序的session共享

    常常有這樣的情況,一個大項目被分割成若干小項目開發(fā),為了能夠互不干擾,要求每個小項目作為一個單獨的web應用程序開發(fā),可是到了最后突然發(fā)現某幾個小項目之間需要共享一些信息,或者想使用session來實現SSO(single sign on),在session中保存login的用戶信息,最自然的要求是應用程序間能夠訪問彼此的session。

    然而按照Servlet規(guī)范,session的作用范圍應該僅僅限于當前應用程序下,不同的應用程序之間是不能夠互相訪問對方的session的。各個應用服務器從實際效果上都遵守了這一規(guī)范,但是實現的細節(jié)卻可能各有不同,因此解決跨應用程序session共享的方法也各不相同。

    首先來看一下Tomcat是如何實現web應用程序之間session的隔離的,從 Tomcat設置的cookie路徑來看,它對不同的應用程序設置的cookie路徑是不同的,這樣不同的應用程序所用的session id是不同的,因此即使在同一個瀏覽器窗口里訪問不同的應用程序,發(fā)送給服務器的session id也可以是不同的。


    image

    根據這個特性,我們可以推測Tomcat中session的內存結構大致如下。
    image

    筆者以前用過的iPlanet也采用的是同樣的方式,估計SunONE與iPlanet之間不會有太大的差別。對于這種方式的服務器,解決的思路很簡單,實際實行起來也不難。要么讓所有的應用程序共享一個session id,要么讓應用程序能夠獲得其他應用程序的session id。

    iPlanet中有一種很簡單的方法來實現共享一個session id,那就是把各個應用程序的cookie路徑都設為/(實際上應該是/NASApp,對于應用程序來講它的作用相當于根)。
    <session-info>
    <path>/NASApp</path>
    </session-info>


    需要注意的是,操作共享的session應該遵循一些編程約定,比如在session attribute名字的前面加上應用程序的前綴,使得 setAttribute("name", "neo")變成setAttribute("app1.name", "neo"),以防止命名空間沖突,導致互相覆蓋。

    在Tomcat中則沒有這么方便的選擇。在Tomcat版本3上,我們還可以有一些手段來共享session。對于版本4以上的Tomcat,目前筆者尚未發(fā)現簡單的辦法。只能借助于第三方的力量,比如使用文件、數據庫、JMS或者客戶端cookie,URL參數或者隱藏字段等手段。

    我們再看一下Weblogic Server是如何處理session的。
    image
    image

    從截屏畫面上可以看到Weblogic Server對所有的應用程序設置的cookie的路徑都是/,這是不是意味著在Weblogic Server中默認的就可以共享session了呢?然而一個小實驗即可證明即使不同的應用程序使用的是同一個session,各個應用程序仍然只能訪問自己所設置的那些屬性。這說明Weblogic Server中的session的內存結構可能如下
    image

    對于這樣一種結構,在 session機制本身上來解決session共享的問題應該是不可能的了。除了借助于第三方的力量,比如使用文件、數據庫、JMS或者客戶端 cookie,URL參數或者隱藏字段等手段,還有一種較為方便的做法,就是把一個應用程序的session放到ServletContext中,這樣另外一個應用程序就可以從ServletContext中取得前一個應用程序的引用。示例代碼如下,

    應用程序A
    context.setAttribute("appA", session); 


    應用程序B
    contextA = context.getContext("/appA");
    HttpSession sessionA = (HttpSession)contextA.getAttribute("appA");


    值得注意的是這種用法不可移植,因為根據ServletContext的JavaDoc,應用服務器可以處于安全的原因對于context.getContext("/appA");返回空值,以上做法在Weblogic Server 8.1中通過。

    那么Weblogic Server為什么要把所有的應用程序的cookie路徑都設為/呢?原來是為了SSO,凡是共享這個session的應用程序都可以共享認證的信息。一個簡單的實驗就可以證明這一點,修改首先登錄的那個應用程序的描述符weblogic.xml,把cookie路徑修改為/appA 訪問另外一個應用程序會重新要求登錄,即使是反過來,先訪問cookie路徑為/的應用程序,再訪問修改過路徑的這個,雖然不再提示登錄,但是登錄的用戶信息也會丟失。注意做這個實驗時認證方式應該使用FORM,因為瀏覽器和web服務器對basic認證方式有其他的處理方式,第二次請求的認證不是通過 session來實現的。具體請參看[7] secion 14.8 Authorization,你可以修改所附的示例程序來做這些試驗。

    八、總結
    session機制本身并不復雜,然而其實現和配置上的靈活性卻使得具體情況復雜多變。這也要求我們不能把僅僅某一次的經驗或者某一個瀏覽器,服務器的經驗當作普遍適用的經驗,而是始終需要具體情況具體分析。
    摘要:雖然session機制在web應用程序中被采用已經很長時間了,但是仍然有很多人不清楚session機制的本質,以至不能正確的應用這一技術。本文將詳細討論session的工作機制并且對在Java web application中應用session機制時常見的問題作出解答。
    posted @ 2006-03-23 21:35 konhon 優(yōu)華 閱讀(412) | 評論 (0)編輯 收藏

    編者注:本文和同系列的前面一文“基于Java的Web服務器工作原理”,都摘自“Tomcat 運行內幕”一書(一本有關 Tomcat 的教程)。在閱讀本文前,最好先閱讀前文,以鞏固基礎信息。在此,將介紹如何建立兩個 servlet 容器。 隨附本書的應用程序可以下載 ,如果您有興趣,可以在近段時間內到 作者網站 下載

      本文介紹一個簡單 servlet 容器的基本原理。現有兩個 servlet 容器,第一個很簡單,第二個則是根據第一個寫出。為了使第一個容器盡量簡單,所以沒有做得很完整。復雜一些的 servlet 容器 (包括 TOMCAT 4 和 5) 在 TOMCAT 運行內幕的其他章節(jié)有介紹。

      兩個 servlet 容器都處理簡單的 servlet 及 staticResource 。您可以使用 webroot/ 目錄下的 PrimitiveServlet 來測試它。復雜一些的 servlet會超出這些容器的容量,您可以從 TOMCAT??運行內幕 一書學習創(chuàng)建復雜的 servlet 容器。

      兩個應用程序的類都封裝在ex02.pyrmont 包下。在理解應用程序如何運作之前,您必須熟悉 javax.servlet.Servlet 接口。首先就來介紹這個接口。隨后,就介紹 servlet 容器服務servlet 的具體內容。


      javax.servlet.Servlet 接口

      servlet 編程,需要引用以下兩個類和接口:javax.servlet 和 javax.servlet.http,在這些類和接口中,javax.servlet.Servlet接口尤為重要。所有的 servlet 必須實現這個接口或繼承已實現這個接口的類。
      Servlet 接口有五個方法,如下:

    &#8226; public void init(ServletConfig config) throws ServletException
    &#8226; public void service(ServletRequest request, ServletResponse response)??throws ServletException, java.io.IOException
    &#8226; public void destroy()
    &#8226; public ServletConfig getServletConfig()
    &#8226; public java.lang.String getServletInfo()


      init、service和 destroy??方法是 Servlet 生命周期的方法。當 Servlet 類實例化后,容器加載 init,以通知 servlet 它已進入服務行列。init 方法必須被加載,Servelt 才能接收和請求。如果要載入數據庫驅動程序、初始化一些值等等,程序員可以重寫這個方法。在其他情況下,這個方法一般為空。

      service 方法由 Servlet 容器調用,以允許 Servlet 響應一個請求。Servlet 容器傳遞 javax.servlet.ServletRequest 對象和 javax.servlet.ServletResponse 對象。ServletRequest 對象包含客戶端 HTTP 請求信息,ServletResponse 則封裝servlet 響應。這兩個對象,您可以寫一些需要 servlet 怎樣服務和客戶怎樣請求的代碼。

      從 service 中刪除 Servlet 實例之前,容器調用 destroy 方法。在 servlet 容器關閉或servlet 容器需要更多的內存時,就調用它。這個方法只有在servlet 的service 方法內的所有線程都退出的時候,或在超時的時候才會被調用。在 servlet 容器調用 destroy方法之后,它將不再調用 servlet的 service方法。destroy 方法給了 servlet 機會,來清除所有候住的資源(比如:內存,文件處理和線程),以確保在內存中所有的持續(xù)狀態(tài)和 servlet的當前狀態(tài)是同步的。Listing 2.1 包含了PrimitiveServlet 的代碼,此servlet非常簡單,您 可以用它來測試本文中的 servlet 容器應用程序。

      PrimitiveServlet 類實現了javax.servlet.Servlet 并提供了五個servlet方法的接口 。它做的事情也很簡單:每次調用 init,service 或 destroy方法的時候,servlet就向控制口寫入方法名。service 方法也從ServletResponsec對象中獲得java.io.PrintWriter 對象,并發(fā)送字符串到瀏覽器。

    Listing 2.1.PrimitiveServlet.java
    import javax.servlet.*;
    import java.io.IOException;
    import java.io.PrintWriter;

    public class PrimitiveServlet implements Servlet {
    ????public void init(ServletConfig config) throws ServletException {
    ????????System.out.println("init");
    ????}

    ????public void service(ServletRequest request, ServletResponse??response) throws ServletException, IOException {
    ????????System.out.println("from service");
    ????????PrintWriter out = response.getWriter();
    ????????out.println("Hello.Roses are red.");
    ????????out.print("Violets are blue.");
    ????}

    ????public void destroy() {
    ????????System.out.println("destroy");
    ????}

    ????public String getServletInfo() {
    ????????return null;
    ????}

    ????public ServletConfig getServletConfig() {
    ????????return null;
    ????}
    }



      Application 1

      現在,我們從 servlet容器的角度來看看 servlet 編程。一個功能健全的 servlet容器對于每個 servlet 的 HTTP請求會完成以下事情:

    &#8226; 當 servlet 第一次被調用的時候,加載了 servlet類并調用它的init方法(僅調用一次)
    &#8226; 響應每次請求的時候 ,構建一個javax.servlet.ServletRequest 和 javax.servlet.ServletResponse實例。
    &#8226; 激活 servlet 的 service 方法,傳遞 ServletRequest 和 ServletResponse 對象。
    &#8226; 當 servlet 類關閉的時候,調用 servlet 的destroy 方法,并卸載 servlet 類。

      發(fā)生在 servlet 容器內部的事就復雜多了。只是這個簡單的 servlet 容器的功能不很健全,所以,這它只能運行非常簡單的servelt ,并不能調用 servlet 的 init 和destroy 方法。然而,它也執(zhí)行了以下動作:

    &#8226; 等待??HTTP 請求。
    &#8226; 構建 ServletRequest 和??ServletResponse 對象??
    &#8226; 如果請求的是一個staticResource,就會激活StaticResourceProcessor實例的 process方法,傳遞ServletRequest 和 ServletResponse 對象。
    &#8226; 如果請求的是一個servlet ,載入該類,并激活它的service 方法,傳遞ServletRequest 和ServletResponse 對象。注意:在這個servlet 容器,每當 servlet被請求的時候該類就被載入。

      在第一個應用程序中,servlet容器由六個類組成 。

    &#8226; HttpServer1
    &#8226; Request
    &#8226; Response
    &#8226; StaticResourceProcessor
    &#8226; ServletProcessor1
    &#8226; Constants

      正如前文中的應用程序一樣,這個程序的進入口(靜態(tài) main 方法)是HttpServer 類。這個方法創(chuàng)建了HttpServer實例,并調用它的await方法。這個方法等待 HTTP 請示,然后創(chuàng)建一個 request 對象和 response對象,根據請求是否是staticResource還是 servlet 來分派它們到 StaticResourceProcessor實例或ServletProcessor實例。

      Constants 類包含 static find WEB_ROOT,它是從其他類引用的。 WEB_ROOT 指明 PrimitiveServlet 位置 和容器服務的staticResource。
    HttpServer1 實例等待 HTTP 請求,直到它收到一個 shutdown 命令。發(fā)布 shutdown命令和前文是一樣的。

      這個應用程序中的每一個類將在下節(jié)介紹。
    posted @ 2006-03-23 20:29 konhon 優(yōu)華 閱讀(514) | 評論 (0)編輯 收藏

    全面解析JDBC(四)
    作者:未知?? ??文章來源:www.jspcn.net
    訪問次數: 次????加入時間:2005-01-19
    如何利用JDBC發(fā)送SQL語句?

      Statement對象用于將SQL語句發(fā)送到數據庫中。實際上有三種Statement對象,它們都作為在給定連接上執(zhí)行SQL語句的包容器:Statement、PreparedStatement(它從Statement繼承而來)和CallableStatement(它從PreparedStatement繼承而來)。它們都專用于發(fā)送特定類型的SQL語句:Statement對象用于執(zhí)行不帶參數的簡單SQL語句;PreparedStatement對象用于執(zhí)行帶或不帶IN參數的預編譯SQL語句;CallableStatement對象用于執(zhí)行對數據庫已存儲過程的調用。

      Statement接口提供了執(zhí)行語句和獲取結果的基本方法;PreparedStatement接口添加了處理IN參數的方法;而CallableStatement添加了處理OUT參數的方法。

      1. 創(chuàng)建Statement對象

      建立了到特定數據庫的連接之后,就可用該連接發(fā)送SQL語句。Statement對象用Connection的方法createStatement創(chuàng)建,如下列代碼段中所示:

    Connection con = DriverManager.getConnection(url,"sunny","");
    Statement stmt = con.createStatement();


      為了執(zhí)行Statement對象,被發(fā)送到數據庫的SQL語句將被作為參數提供給Statement的方法:

      ResultSet rs = stmt.executeQuery("SELECT a,b,c FROM Table2");

      2. 使用Statement對象執(zhí)行語句

      Statement接口提供了三種執(zhí)行SQL語句的方法:executeQuery、executeUpdate和execute。使用哪一個方法由SQL語句所產生的內容決定。

      方法executeQuery用于產生單個結果集的語句,例如SELECT語句。方法executeUpdate用于執(zhí)行INSERT、UPDATE或DELETE語句以及SQL DDL(數據定義語言)語句,例如CREATE TABLE和DROP TABLE。INSERT、UPDATE或DELETE語句的效果是修改表中零行或多行中的一列或多列。executeUpdate的返回值是一個整數,指示受影響的行數(即更新計數)。對于CREATE TABLE或DROP TABLE等不操作行的語句,executeUpdate的返回值總為零。

      執(zhí)行語句的所有方法都將關閉所調用的Statement對象的當前打開結果集(如果存在)。這意味著在重新執(zhí)行Statement對象之前,需要完成對當前ResultSet對象的處理。應注意,繼承了Statement接口中所有方法的PreparedStatement接口都有自己的executeQuery、executeUpdate和execute方法。Statement對象本身不包含SQL語句,因而必須給Statement.execute方法提供SQL語句作為參數。PreparedStatement對象并不需要SQL語句作為參數提供給這些方法,因為它們已經包含預編譯SQL語句。

      CallableStatement對象繼承這些方法的PreparedStatement形式。對于這些方法的PreparedStatement或CallableStatement版本,使用查詢參數將拋出SQLException。

      3. 語句完成

      當連接處于自動提交模式時,其中所執(zhí)行的語句在完成時將自動提交或還原。語句在已執(zhí)行且所有結果返回時,即認為已完成。對于返回一個結果集的executeQuery方法,在檢索完ResultSet對象的所有行時該語句完成。對于方法executeUpdate,當它執(zhí)行時語句即完成。但在少數調用方法execute的情況中,在檢索所有結果集或它生成的更新計數之后語句才完成。

      有些DBMS將已存儲過程中的每條語句視為獨立的語句;而另外一些則將整個過程視為一個復合語句。在啟用自動提交時,這種差別就變得非常重要,因為它影響什么時候調用commit方法。在前一種情況中,每條語句單獨提交;在后一種情況中,所有語句同時提交。

      4. 關閉Statement對象

      Statement對象將由Java垃圾收集程序自動關閉。而作為一種好的編程風格,應在不需要Statement對象時顯式地關閉它們。這將立即釋放DBMS資源,有助于避免潛在的內存問題。

      5. 使用方法execute

      execute方法應該僅在語句能返回多個ResultSet對象、多個更新計數或ResultSet對象與更新計數的組合時使用。當執(zhí)行某個已存儲過程或動態(tài)執(zhí)行未知SQL字符串(即應用程序程序員在編譯時未知)時,有可能出現多個結果的情況,盡管這種情況很少見。例如,用戶可能執(zhí)行一個已存儲過程,并且該已存儲過程可執(zhí)行更新,然后執(zhí)行選擇,再進行更新,再進行選擇,等等。通常使用已存儲過程的人應知道它所返回的內容。

      因為方法execute處理非常規(guī)情況,所以獲取其結果需要一些特殊處理并不足為怪。例如,假定已知某個過程返回兩個結果集,則在使用方法execute執(zhí)行該過程后,必須調用方法getResultSet獲得第一個結果集,然后調用適當的getXXX方法獲取其中的值。要獲得第二個結果集,需要先調用getMoreResults方法,然后再調用getResultSet方法。如果已知某個過程返回兩個更新計數,則首先調用方法getUpdateCount,然后調用getMoreResults,并再次調用getUpdateCount。

      對于不知道返回內容,則情況更為復雜。如果結果是ResultSet對象,則方法execute返回true;如果結果是Javaint,則返回false。如果返回int,則意味著結果是更新計數或執(zhí)行的語句是DL命令。在調用方法execute之后要做的第一件事情是調用getResultSet或getUpdateCount。調用方法getResultSet可以獲得兩個或多個ResultSet對象中第一個對象;或調用方法getUpdateCount可以獲得兩個或多個更新計數中第一個更新計數的內容。

      當SQL語句的結果不是結果集時,則方法getResultSet將返回null。這可能意味著結果是一個更新計數或沒有其它結果。在這種情況下,判斷null真正含義的唯一方法是調用方法getUpdateCount,它將返回一個整數。這個整數為調用語句所影響的行數;如果為-1則表示結果是結果集或沒有結果。如果方法getResultSet已返回null(表示結果不是ResultSet對象),則返回值-1表示沒有其它結果。也就是說,當下列條件為真時表示沒有結果(或沒有其它結果):

      ((stmt.getResultSet()==null)&&(stmt.getUpdateCount()==-1))

      如果已經調用方法getResultSet并處理了它返回的ResultSet對象,則有必要調用方法getMoreResults以確定是否有其它結果集或更新計數。如果getMoreResults返回true,則需要再次調用getResultSet來檢索下一個結果集。如上所述,如果getResultSet返回null,則需要調用getUpdateCount來檢查null是表示結果為更新計數還是表示沒有其它結果。

      當getMoreResults返回false時,它表示該SQL語句返回一個更新計數或沒有其它結果。因此需要調用方法getUpdateCount來檢查它是哪一種情況。在這種情況下,當下列條件為真時表示沒有其它結果:

      ((stmt.getMoreResults()==false)&&(stmt.getUpdateCount()==-1))

      下面的代碼演示了一種方法用來確認已訪問調用方法execute所產生的全部結果集和更新計數:

    stmt.execute(queryStringWithUnknownResults);
    while(true){
    introwCount=stmt.getUpdateCount();
    if(rowCount>0){//它是更新計數
    System.out.println("Rows changed="+count);
    stmt.getMoreResults();
    continue;
    }
    if(rowCount==0){//DDL命令或0個更新
    System.out.println("No rows changed or statement was DDL command");
    stmt.getMoreResults();
    continue;
    }
    //執(zhí)行到這里,證明有一個結果集
    //或沒有其它結果
    ResultSet rs=stmt.getResultSet();
    if(rs!=null){
    ...//使用元數據獲得關于結果集列的信息
    while(rs.next()){
    ...//處理結果
    stmt.getMoreResults();
    continue;
    }
    break;//沒有其它結果
     
    posted @ 2006-03-22 20:46 konhon 優(yōu)華 閱讀(409) | 評論 (0)編輯 收藏

    全面解析JDBC(三)
    作者:未知?? ??文章來源:www.jspcn.net
    訪問次數: 次????加入時間:2005-01-19
    JDBC驅動管理內幕是怎么樣的?

      DriverManager 類是 JDBC 的管理層,作用于用戶和驅動程序之間。它跟蹤可用的驅動程序,并在數據庫和相應驅動程序之間建立連接。另外,DriverManager類也處理諸如驅動程序登錄時間限制及登錄和跟蹤消息的顯示等事務。

      對于簡單的應用程序,一般程序員需要在此類中直接使用的唯一方法是DriverManager.getConnection。正如名稱所示,該方法將建立與數據庫的連接。JDBC允許用戶調用DriverManager的方法getDriver、getDrivers和registerDriver及Driver的方法connect。但多數情況下,讓DriverManager類管理建立連接的細節(jié)為上策。

      1. 跟蹤可用驅動程序

      DriverManager類包含一列Driver類,它們已通過調用方法DriverManager.registerDriver對自己進行了注冊。所有Driver類都必須包含有一個靜態(tài)部分。它創(chuàng)建該類的實例,然后在加載該實例時DriverManager類進行注冊。這樣,用戶正常情況下將不會直接調用DriverManager.registerDriver;而是在加載驅動程序時由驅動程序自動調用。加載Driver類,然后自動在DriverManager中注冊的方式有兩種:

      (1)調用方法Class.forName

      這將顯式地加載驅動程序類。由于這與外部設置無關,因此推薦使用這種加載驅動程序的方法。以下代碼加載類acme.db.Driver:Class.forName("acme.db.Driver")。

      如果將acme.db.Driver編寫為加載時創(chuàng)建實例,并調用以該實例為參數的DriverManager.registerDriver(本該如此),則它在DriverManager的驅動程序列表中,并可用于創(chuàng)建連接。

      (2)將驅動程序添加到Java.lang.System的屬性jdbc.drivers中

      這是一個由DriverManager類加載的驅動程序類名的列表,由冒號分隔:初始化DriverManager類時,它搜索系統(tǒng)屬性jdbc.drivers,如果用戶已輸入了一個或多個驅動程序,則DriverManager類將試圖加載它們。以下代碼說明程序員如何在~/.hotJava/properties中輸入三個驅動程序類(啟動時,HotJava將把它加載到系統(tǒng)屬性列表中):

      jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.test.ourDriver;

      對DriverManager方法的第一次調用將自動加載這些驅動程序類。注意:加載驅動程序的第二種方法需要持久的預設環(huán)境。如果對這一點不能保證,則調用方法Class.forName顯式地加載每個驅動程序就顯得更為安全。這也是引入特定驅動程序的方法,因為一旦DriverManager類被初始化,它將不再檢查jdbc.drivers屬性列表。

      在以上兩種情況中,新加載的Driver類都要通過調用DriverManager.registerDriver類進行自我注冊。如上所述,加載類時將自動執(zhí)行這一過程。

      由于安全方面的原因,JDBC管理層將跟蹤哪個類加載器提供哪個驅動程序。這樣,當DriverManager類打開連接時,它僅使用本地文件系統(tǒng)或與發(fā)出連接請求的代碼相同的類加載器提供的驅動程序。

      2. 建立連接

      加載Driver類并在DriverManager類中注冊后,它們即可用來與數據庫建立連接。當調用DriverManager.getConnection方法發(fā)出連接請求時,DriverManager將檢查每個驅動程序,查看它是否可以建立連接。

      有時可能有多個JDBC驅動程序可以與給定的URL連接。例如,與給定遠程數據庫連接時,可以使用JDBC-ODBC橋驅動程序、JDBC到通用網絡協議驅動程序或數據庫廠商提供的驅動程序。在這種情況下測試驅動程序的順序至關重要,因為DriverManager將使用它所找到的第一個可以成功連接到給定URL的驅動程序。

      首先DriverManager試圖按注冊的順序使用每個驅動程序(jdbc.drivers中列出的驅動程序總是先注冊)。它將跳過代碼不可信任的驅動程序,除非加載它們的源與試圖打開連接的代碼的源相同。它通過輪流在每個驅動程序上調用方法Driver.connect,并向它們傳遞用戶開始傳遞給方法DriverManager.getConnection的URL來對驅動程序進行測試,然后連接第一個認出該URL的驅動程序。這種方法初看起來效率不高,但由于不可能同時加載數十個驅動程序,因此每次連接實際只需幾個過程調用和字符串比較。

      以下代碼是通常情況下用驅動程序(例如JDBC-ODBC橋驅動程序)建立連接所需所有步驟的示例:



    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");//加載驅動程序
    String url = "jdbc:odbc:fred";
    DriverManager.getConnection(url,"userID","passwd");
    posted @ 2006-03-22 20:45 konhon 優(yōu)華 閱讀(382) | 評論 (0)編輯 收藏

    全面解析JDBC(二)
    作者:未知?? ??文章來源:www.jspcn.net
    訪問次數: 次????加入時間:2005-01-19
    如何建立JDBC連接?

      Connection 對象代表與數據庫的連接。連接過程包括所執(zhí)行的 SQL 語句和在該連接上所返回的結果。一個應用程序可與單個數據庫有一個或多個連接,或者可與許多數據庫有連接。

      1. 打開連接

      與數據庫建立連接的標準方法是調用DriverManager.getConnection方法。該方法接受含有某個URL的字符串。DriverManager類(即所謂的JDBC管理層)將嘗試找到可與那個URL所代表的數據庫進行連接的驅動程序。DriverManager類存有已注冊的Driver類的清單。當調用方法getConnection時,它將檢查清單中的每個驅動程序,直到找到可與URL中指定的數據庫進行連接的驅動程序為止。Driver的方法connect使用這個URL來建立實際的連接。

      用戶可繞過JDBC管理層直接調用Driver方法。這在以下特殊情況下將很有用:當兩個驅動器可同時連接到數據庫中,而用戶需要明確地選用其中特定的驅動器。但一般情況下,讓DriverManager類處理打開連接這種事將更為簡單。

      下述代碼顯示如何打開一個與位于URL"jdbc:odbc:wombat"的數據庫的連接。所用的用戶標識符為"freely",口令為"ec":

      String url = "jdbc:odbc:wombat";
      Connection con = DriverManager.getConnection(url, "freely", "ec");

      2. 一般用法的URL

      由于URL常引起混淆,我們將先對一般URL作簡單說明,然后再討論JDBCURL。URL(統(tǒng)一資源定位符)提供在Internet上定位資源所需的信息。可將它想象為一個地址。URL的第一部份指定了訪問信息所用的協議,后面總是跟著冒號。常用的協議有"ftp"(代表"文件傳輸協議")和"http"(代表"超文本傳輸協議")。如果協議是"file",表示資源是在某個本地文件系統(tǒng)上而非在Internet上(下例用于表示我們所描述的部分;它并非URL的組成部分)。

      ftp://Javasoft.com/docs/JDK-1_apidocs.zip
      http://Java.sun.com/products/jdk/CurrentRelease
      file:/home/haroldw/docs/books/tutorial/summary.html

      URL的其余部份(冒號后面的)給出了數據資源所處位置的有關信息。如果協議是file,則URL的其余部份是文件的路徑。對于ftp和http協議,URL的其余部份標識了主機并可選地給出某個更詳盡的地址路徑。例如,以下是JavaSoft主頁的URL。該URL只標識了主機:http://Java.sun.com。從該主頁開始瀏覽,就可以進到許多其它的網頁中,其中之一就是JDBC主頁。JDBC主頁的URL更為具體,它具體表示為:
    http://Java.sun.com/products/jdbc

      3. JDBC URL

      JDBC URL提供了一種標識數據庫的方法,可以使相應的驅動程序能識別該數據庫并與之建立連接。實際上,驅動程序編程員將決定用什么JDBC URL來標識特定的驅動程序。用戶不必關心如何來形成JDBC URL;他們只須使用與所用的驅動程序一起提供的URL即可。JDBC的作用是提供某些約定,驅動程序編程員在構造他們的JDBC URL時應該遵循這些約定。

      由于JDBC URL要與各種不同的驅動程序一起使用,因此這些約定應非常靈活。首先,它們應允許不同的驅動程序使用不同的方案來命名數據庫。例如,odbc子協議允許(但并不是要求)URL含有屬性值。

      其次,JDBC URL應允許驅動程序編程員將一切所需的信息編入其中。這樣就可以讓要與給定數據庫對話的applet打開數據庫連接,而無須要求用戶去做任何系統(tǒng)管理工作。

      最后,JDBC URL應允許某種程度的間接性。也就是說,JDBC URL可指向邏輯主機或數據庫名,而這種邏輯主機或數據庫名將由網絡命名系統(tǒng)動態(tài)地轉換為實際的名稱。這可以使系統(tǒng)管理員不必將特定主機聲明為JDBC名稱的一部份。網絡命名服務(例如DNS、NIS和DCE)有多種,而對于使用哪種命名服務并無限制。
    JDBC URL的標準語法如下所示。它由三部分組成,各部分間用冒號分隔:
    jdbc:<子協遙荊海甲用?稱??br>   JDBC URL的三個部分可分解如下:

      (1)jdbc協議:JDBC URL中的協議總是jdbc。

      (2)<子協議>:驅動程序名或數據庫連接機制(這種機制可由一個或多個驅動程序支持)的名稱。子協議名的典型示例是"odbc",該名稱是為用于指定ODBC風格的數據資源名稱的URL專門保留的。例如,為了通過JDBC-ODBC橋來訪問某個數據庫,可以用如下所示的URL:jdbc:odbc:book。本例中,子協議為"odbc",子名稱"book"是本地ODBC數據資源。如果要用網絡命名服務(這樣JDBC URL中的數據庫名稱不必是實際名稱),則命名服務可以作為子協議。例如,可用如下所示的URL:jdbc:dcenaming:accounts。本例中,該URL指定了本地DCE命名服務應該將數據庫名稱"accounts"解析為更為具體的可用于連接真實數據庫的名稱。

      (3)<子名稱>:種標識數據庫的方法。子名稱可以依不同的子協議而變化。它還可以有子名稱的子名稱(含有驅動程序編程員所選的任何內部語法)。使用子名稱的目的是為定位數據庫提供足夠的信息。前例中,因為ODBC將提供其余部份的信息,因此用"book"就已足夠。然而,位于遠程服務器上的數據庫需要更多的信息。例如,如果數據庫是通過Internet來訪問的,則在JDBC URL中應將網絡地址作為子名稱的一部份包括進去,且必須遵循如下所示的標準URL命名約定://主機名:端口/子協議。

      假設"dbnet"是個用于將某個主機連接到Internet上的協議,則JDBC URL應為:jdbc:dbnet://wombat:356/fred。

      4. "odbc"子協議

      子協議odbc是一種特殊情況。它是為用于指定ODBC風格的數據資源名稱的URL而保留的,并具有下列特性:允許在子名稱(數據資源名稱)后面指定任意多個屬性值。odbc子協議的完整語法為:

      jdbc:odbc:<數據資源名稱>[;<屬性名>=<屬性值>],因此,以下都是合法的jdbc:odbc名稱:
      jdbc:odbc:qeor7
      jdbc:odbc:wombat
      jdbc:odbc:wombat;CacheSize=20;ExtensionCase=LOWER
      jdbc:odbc:qeora;UID=kgh;PWD=fooey

      5. 注冊子協議

      驅動程序編程員可保留某個名稱以將之用作JDBC URL的子協議名。當DriverManager類將此名稱加到已注冊的驅動程序清單中時,為之保留該名稱的驅動程序應能識別該名稱并與它所標識的數據庫建立連接。例如,odbc是為JDBC-ODBC橋而保留的。假設有個Miracle公司,它可能會將"miracle"注冊為連接到其Miracle DBMS上的JDBC驅動程序的子協議,從而使其他人都無法使用這個名稱。

      JavaSoft目前作為非正式代理負責注冊JDBC子協議名稱。要注冊某個子協議名稱,請發(fā)送電子郵件到下述地址:jdbc@wombat.eng.sun.com。

      6. 發(fā)送SQL語句

      連接一旦建立,就可用來向它所涉及的數據庫傳送SQL語句。JDBC對可被發(fā)送的SQL語句類型不加任何限制。這就提供了很大的靈活性,即允許使用特定的數據庫語句或甚至于非SQL語句。然而,它要求用戶自己負責確保所涉及的數據庫可以處理所發(fā)送的SQL語句,否則將自食其果。例如,如果某個應用程序試圖向不支持儲存程序的DBMS發(fā)送儲存程序調用,就會失敗并將拋出異常。JDBC要求驅動程序應至少能提供ANSI SQL-2 Entry Level功能才可算是符合JDBC標準TM的。這意味著用戶至少可信賴這一標準級別的功能。

      JDBC提供了三個類,用于向數據庫發(fā)送SQL語句。Connection接口中的三個方法可用于創(chuàng)建這些類的實例。下面列出這些類及其創(chuàng)建方法:

      (1)Statement:由方法createStatement所創(chuàng)建。Statement對象用于發(fā)送簡單的SQL語句。

      (2)PreparedStatement:由方法prepareStatement所創(chuàng)建。PreparedStatement對象用于發(fā)送帶有一個或多個輸入參數(IN參數)的SQL語句。PreparedStatement擁有一組方法,用于設置IN參數的值。執(zhí)行語句時,這些IN參數將被送到數據庫中。PreparedStatement的實例擴展了Statement,因此它們都包括了Statement的方法。PreparedStatement對象有可能比Statement對象的效率更高,因為它已被預編譯過并存放在那以供將來使用。

      (3)CallableStatement:由方法prepareCall所創(chuàng)建。CallableStatement對象用于執(zhí)行SQL儲存程序─一組可通過名稱來調用(就象函數的調用那樣)的SQL語句。CallableStatement對象從PreparedStatement中繼承了用于處理IN參數的方法,而且還增加了用于處理OUT參數和INOUT參數的方法。

      不過通常來說createStatement方法用于簡單的SQL語句(不帶參數)、prepareStatement方法用于帶一個或多個IN參數的SQL語句或經常被執(zhí)行的簡單SQL語句,而prepareCall方法用于調用已儲存過程。

      7. 事務

      事務由一個或多個這樣的語句組成:這些語句已被執(zhí)行、完成并被提交或還原。當調用方法commit或rollback時,當前事務即告就結束,另一個事務隨即開始。缺省情況下,新連接將處于自動提交模式。也就是說,當執(zhí)行完語句后,將自動對那個語句調用commit方法。這種情況下,由于每個語句都是被單獨提交的,因此一個事務只由一個語句組成。如果禁用自動提交模式,事務將要等到commit或rollback方法被顯式調用時才結束,因此它將包括上一次調用commit或rollback方法以來所有執(zhí)行過的語句。對于第二種情況,事務中的所有語句將作為組來提交或還原。

      方法commit使SQL語句對數據庫所做的任何更改成為永久性的,它還將釋放事務持有的全部鎖。而方法rollback將棄去那些更改。有時用戶在另一個更改生效前不想讓此更改生效。這可通過禁用自動提交并將兩個更新組合在一個事務中來達到。如果兩個更新都是成功,則調用commit方法,從而使兩個更新結果成為永久性的;如果其中之一或兩個更新都失敗了,則調用rollback方法,以將值恢復為進行更新之前的值。

      大多數JDBC驅動程序都支持事務。事實上,符合JDBC的驅動程序必須支持事務。DatabaseMetaData給出的信息描述DBMS所提供的事務支持水平。

      8. 事務隔離級別

      如果DBMS支持事務處理,它必須有某種途徑來管理兩個事務同時對一個數據庫進行操作時可能發(fā)生的沖突。用戶可指定事務隔離級別,以指明DBMS應該花多大精力來解決潛在沖突。例如,當事務更改了某個值而第二個事務卻在該更改被提交或還原前讀取該值時該怎么辦。

      假設第一個事務被還原后,第二個事務所讀取的更改值將是無效的,那么是否可允許這種沖突?JDBC用戶可用以下代碼來指示DBMS允許在值被提交前讀取該值("dirty讀取"),其中con是當前連接:
    con.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED);

      事務隔離級別越高,為避免沖突所花的精力也就越多。Connection接口定義了五級,其中最低級別指定了根本就不支持事務,而最高級別則指定當事務在對某個數據庫進行操作時,任何其它事務不得對那個事務正在讀取的數據進行任何更改。通常,隔離級別越高,應用程序執(zhí)行的速度也就越慢(由于用于鎖定的資源耗費增加了,而用戶間的并發(fā)操作減少了)。在決定采用什么隔離級別時,開發(fā)人員必須在性能需求和數據一致性需求之間進行權衡。當然,實際所能支持的級別取決于所涉及的DBMS的功能。

      當創(chuàng)建Connection對象時,其事務隔離級別取決于驅動程序,但通常是所涉及的數據庫的缺省值。用戶可通過調用setIsolationLevel方法來更改事務隔離級別。新的級別將在該連接過程的剩余時間內生效。要想只改變一個事務的事務隔離級別,必須在該事務開始前進行設置,并在該事務結束后進行復位。我們不提倡在事務的中途對事務隔離級別進行更改,因為這將立即觸發(fā)commit方法的調用,使在此之前所作的任何更改變成永久性的。
    posted @ 2006-03-22 20:44 konhon 優(yōu)華 閱讀(394) | 評論 (0)編輯 收藏

    全面解析JDBC(一)
    作者:未知?? ??文章來源:www.jspcn.net
    訪問次數: 次????加入時間:2005-01-19
    綜述:Java數據庫連接體系結構是用于Java應用程序連接數據庫的標準方法。JDBC對Java程序員而言是API,對實現與數據庫連接的服務提供商而言是接口模型。作為API,JDBC為程序開發(fā)提供標準的接口,并為數據庫廠商及第三方中間件廠商實現與數據庫的連接提供了標準方法。JDBC使用已有的SQL標準并支持與其它數據庫連接標準,如ODBC之間的橋接。JDBC實現了所有這些面向標準的目標并且具有簡單、嚴格類型定義且高性能實現的接口。

      如何選擇合適的JDBC產品?

      有關JDBC最新的信息,有興趣的讀者可以查閱JDBC的官方網站--即JavaSoft的主頁,其URL為:http://Java.sun.com/products/jdbc

      1. JavaSoft框架

      JavaSoft提供三種JDBC產品組件,它們是Java開發(fā)工具包(JDK)的組成部份:JDBC驅動程序管理器、JDBC驅動程序測試工具包和JDBC-ODBC橋。

      JDBC驅動程序管理器是JDBC體系結構的支柱。它實際上很小,也很簡單;其主要作用是把Java應用程序連接到正確的JDBC驅動程序上,然后即退出。

      JDBC驅動程序測試工具包為使JDBC驅動程序運行您的程序提供一定的可信度。只有通過JDBC驅動程序測試的驅動程序才被認為是符合JDBC標準TM的。

      JDBC-ODBC橋使ODBC驅動程序可被用作JDBC驅動程序。它的實現為JDBC的快速發(fā)展提供了一條途徑,其長遠目標提供一種訪問某些不常見的DBMS(如果對這些不常見的DBMS未實現JDBC)的方法。

      2. JDBC驅動程序的類型

      目前比較常見的JDBC驅動程序可分為以下四個種類:

      (1)JDBC-ODBC橋加ODBC驅動程序

      JavaSoft橋產品利用ODBC驅動程序提供JDBC訪問。注意,必須將ODBC二進制代碼(許多情況下還包括數據庫客戶機代碼)加載到使用該驅動程序的每個客戶機上。因此,這種類型的驅動程序最適合于企業(yè)網(這種網絡上客戶機的安裝不是主要問題),或者是用Java編寫的三層結構的應用程序服務器代碼。

      (2)本地API

      這種類型的驅動程序把客戶機API上的JDBC調用轉換為Oracle、Sybase、Informix、DB2或其它DBMS的調用。注意,象橋驅動程序一樣,這種類型的驅動程序要求將某些二進制代碼加載到每臺客戶機上。

      (3)JDBC網絡純Java驅動程序

      這種驅動程序將JDBC轉換為與DBMS無關的網絡協議,之后這種協議又被某個服務器轉換為一種DBMS協議。這種網絡服務器中間件能夠將它的純Java客戶機連接到多種不同的數據庫上。所用的具體協議取決于提供者。通常,這是最為靈活的JDBC驅動程序。有可能所有這種解決方案的提供者都提供適合于Intranet用的產品。為了使這些產品也支持Internet訪問,它們必須處理Web所提出的安全性、通過防火墻的訪問等方面的額外要求。幾家提供者正將JDBC驅動程序加到他們現有的數據庫中間件產品中。

      (4)本地協議純Java驅動程序

      這種類型的驅動程序將JDBC調用直接轉換為DBMS所使用的網絡協議。這將允許從客戶機機器上直接調用DBMS服務器,是Intranet訪問的一個很實用的解決方法。由于許多這樣的協議都是專用的,因此數據庫提供者自己將是主要來源,有幾家提供者已在著手做這件事了。

      據專家預計第(3)、(4)類驅動程序將成為從JDBC訪問數據庫的首方法。第(1)、(2)類驅動程序在直接的純Java驅動程序還沒有上市前會作為過渡方案來使用。對第(1)、(2)類驅動程序可能會有一些變種,這些變種要求有連接器,但通常這些是更加不可取的解決方案。第(3)、(4)類驅動程序提供了Java的所有優(yōu)點,包括自動安裝(例如,通過使用JDBC驅動程序的appletapplet來下載該驅動程序)。

      3. JDBC驅動程序的獲取



      目前已有幾十個(1)類的驅動程序,即可與Javasoft橋聯合使用的ODBC驅動程序的驅動程序。有大約十多個屬于種類(2)的驅動程序是以DBMS的本地API為基礎編寫的。只有幾個屬于種類(3)的驅動程序,其首批提供者是SCO、OpenHorizon、Visigenic和WebLogic。此外,JavaSoft和數據庫連接的領先提供者Intersolv還合作研制了JDBC-ODBC橋和JDBC驅動程序測試工具包。
    posted @ 2006-03-22 20:44 konhon 優(yōu)華 閱讀(484) | 評論 (0)編輯 收藏

    你插入數據的時候,用
    /**
    *?轉變字符串的亂碼函數
    *?
    @param ?str
    *?
    @return
    */

    public ?String?getStr(String?str)
    {
    try {
    String?temp_p?
    = ?str;
    byte ?[]?temp_t? = ?temp_p.getBytes( " ISO8859-1 " );
    String?temp?
    = ? new ?String(temp_t);
    return ?temp;
    }

    catch (Exception?e) {
    return ? " null " ;
    }

    }
    ?
    // 向bean里面賦值
    public ? void ?setAction(String?action)? {
    this .action? = ?getStr(action);
    }


    public ? void ?setAddmanagerid(String?addmanagerid)? {
    this .addmanagerid? = ?getStr(addmanagerid);
    }


    轉換一下,看看可以嗎,我的數據庫是ORACLE沒問題。
    posted @ 2006-03-22 19:06 konhon 優(yōu)華 閱讀(419) | 評論 (0)編輯 收藏

    Java編程電子書籍下載


    環(huán)境安裝配置:

    TOMCAT的配置
    http://download.chinaitlab.com/soft/10791.htm

    JAVA配置文件編寫說明文檔
    http://download.chinaitlab.com/soft/10010.htm

    一步一步學會配置Kjava開發(fā)環(huán)境
    http://download.chinaitlab.com/soft/9483.htm

    Weblogic7開發(fā)EJB的配置
    http://download.chinaitlab.com/soft/4938.htm

    圖解JSP環(huán)境安裝配置
    http://download.chinaitlab.com/soft/2157.htm

    Tomcat配置方法
    http://download.chinaitlab.com/soft/931.htm

    全程指導Linux下JAVA環(huán)境配置
    http://download.chinaitlab.com/soft/11272.htm

    學習方法:

    通過JB4學習JAVA
    http://download.chinaitlab.com/soft/7589.htm

    10步學習 JavaScript
    http://download.chinaitlab.com/soft/6492.htm

    Java Sctipt學習不求人
    http://download.chinaitlab.com/soft/6361.htm

    JSP學習指南
    http://download.chinaitlab.com/soft/6152.htm

    JAVA學習文檔
    http://download.chinaitlab.com/soft/6114.htm

    J2EE學習筆記
    http://download.chinaitlab.com/soft/6048.htm

    JavaScript學習
    http://download.chinaitlab.com/soft/3029.htm

    Java2 學習指南
    http://download.chinaitlab.com/soft/2743.htm

    Juniper學習指南
    http://download.chinaitlab.com/soft/2227.htm

    J2EE學習資料
    http://download.chinaitlab.com/soft/1618.htm

    JSP由淺入深
    http://download.chinaitlab.com/soft/1315.htm

    面向對象編程:

    Java面向對象編程指南
    http://download.chinaitlab.com/soft/9792.htm

    JAVA的核心技術:面向對象編程
    http://download.chinaitlab.com/soft/9093.htm

    Java 與 UML 面向對象程序設計
    http://download.chinaitlab.com/soft/6053.htm

    Java 2 編程21天自學通
    http://download.chinaitlab.com/soft/10507.htm

    J2EE編程起步
    http://download.chinaitlab.com/soft/10506.htm

    Java面向對象編程指南
    http://download.chinaitlab.com/soft/9792.htm

    Java專業(yè)編程指南
    http://download.chinaitlab.com/soft/9791.htm

    Java服務器高級編程
    http://download.chinaitlab.com/soft/9790.htm

    J2EE EAI編程指南
    http://download.chinaitlab.com/soft/9784.htm

    J2MEMIDP無線設備編程指南
    http://download.chinaitlab.com/soft/9765.htm

    JAVA編程思想 中文版
    http://download.chinaitlab.com/soft/9481.htm

    Java XML編程指南
    http://download.chinaitlab.com/soft/9097.htm

    Java 數據庫編程寶典
    http://download.chinaitlab.com/soft/9095.htm

    JAVA的核心技術:面向對象編程
    http://download.chinaitlab.com/soft/9093.htm

    JDBC API數據庫編程實作教材
    http://download.chinaitlab.com/soft/9087.htm

    核心 JSF 編程
    http://download.chinaitlab.com/soft/7946.htm

    JAVA 2應用編程150例
    http://download.chinaitlab.com/soft/6815.htm

    JAVA數據庫編程JDBC
    http://download.chinaitlab.com/soft/6113.htm

    深入掌握J2EE編程技術
    http://download.chinaitlab.com/soft/6030.htm

    實用J2EE設計模式編程指南
    http://download.chinaitlab.com/soft/5033.htm

    Java for Internet編程技術
    http://download.chinaitlab.com/soft/4198.htm

    Java安全性編程指南
    http://download.chinaitlab.com/soft/3773.htm

    J2ME無線設備編程
    http://download.chinaitlab.com/soft/3669.htm

    J2EE EJB編程實例
    http://download.chinaitlab.com/soft/3141.htm

    Java編程思想 第三版
    http://download.chinaitlab.com/soft/2982.htm

    Java 極限編程
    http://download.chinaitlab.com/soft/1707.htm

    Java2編程詳解
    http://download.chinaitlab.com/soft/1705.htm


    網絡編程:

    J2EE網絡編程標準教程
    http://download.chinaitlab.com/soft/9100.htm

    Java網絡編程實例
    http://download.chinaitlab.com/soft/9090.htm

    Java P2P網絡編程技術
    http://download.chinaitlab.com/soft/6333.htm

    Java網絡編程
    http://download.chinaitlab.com/soft/3871.htm

    網絡編程基礎篇之 Java Script
    http://download.chinaitlab.com/soft/3618.htm

    Solaris Shell 編程
    http://download.chinaitlab.com/soft/6426.htm

    SUN Solaris管理手冊
    http://download.chinaitlab.com/soft/5732.htm

    Solaris性能管理
    http://download.chinaitlab.com/soft/11247.htm

    Solaris9安裝指南
    http://download.chinaitlab.com/soft/5022.htm

    SOLARIS高級系統(tǒng)管理員指南
    http://download.chinaitlab.com/soft/3726.htm

    Solaris操作環(huán)境安全
    http://download.chinaitlab.com/soft/1500.htm

    Solaris GNOME2.0桌面用戶指南
    http://download.chinaitlab.com/soft/1488.htm

    Solaris 9 12/03 安裝指南
    http://download.chinaitlab.com/soft/1484.htm

    Solaris管理員指南
    http://download.chinaitlab.com/soft/1475.htm

    中文Solaris9 系統(tǒng)管理員指南
    http://download.chinaitlab.com/soft/1463.htm

    Solaris安全性專題指導
    http://download.chinaitlab.com/soft/746.htm


    XML系列:

    Java XML編程指南
    http://download.chinaitlab.com/soft/9097.htm

    Java程序設計EJB、XML與數據庫
    http://download.chinaitlab.com/soft/9094.htm

    XML 終極教程
    http://download.chinaitlab.com/soft/9057.htm

    Java&XML應用
    http://download.chinaitlab.com/soft/6211.htm

    XML_JAVA指南
    http://download.chinaitlab.com/soft/6163.htm

    JDBC:

    JDBC API數據庫編程實作教材
    http://download.chinaitlab.com/soft/9087.htm

    JAVA數據庫編程JDBC
    http://download.chinaitlab.com/soft/6113.htm

    JDBC API 參考教程第三版
    http://download.chinaitlab.com/soft/6057.htm

    JDBC與Java數據庫程序設計
    http://download.chinaitlab.com/soft/6018.htm

    Java語言SQL接口 JDBCprogram
    http://download.chinaitlab.com/soft/5938.htm

    JSP應用程序開發(fā)指南
    http://download.chinaitlab.com/soft/1546.htm

    用 JDBC 管理數據庫連接
    http://download.chinaitlab.com/soft/935.htm

    JDO:

    全面了解JDO數據庫編程
    http://download.chinaitlab.com/soft/7992.htm

    Struts:

    Struts中文手冊
    http://download.chinaitlab.com/soft/10516.htm

    Struts架構指導
    http://download.chinaitlab.com/soft/7529.htm

    精通struts技術
    http://download.chinaitlab.com/soft/6801.htm

    Struts 學習起歩問答
    http://download.chinaitlab.com/soft/6156.htm

    Hibernate:

    Hibernate2.1.2參考手冊中文版
    http://download.chinaitlab.com/soft/8919.htm



    JAVA與模式\J2EE模式:

    J2EE 核心模式
    http://download.chinaitlab.com/soft/9785.htm

    Java 企業(yè)設計模式
    http://download.chinaitlab.com/soft/9096.htm

    Java簡單工廠創(chuàng)立性模式介紹
    http://download.chinaitlab.com/soft/7398.htm

    EJB設計模式
    http://download.chinaitlab.com/soft/6135.htm

    JAVA設計模式
    http://download.chinaitlab.com/soft/6112.htm

    實用J2EE設計模式編程指南
    http://download.chinaitlab.com/soft/5033.htm

    Java與模式
    http://download.chinaitlab.com/soft/3073.htm

    設計模式Java版
    http://download.chinaitlab.com/soft/1723.htm


    JBuilder開發(fā)Servlet及JSP:

    精通JBuilder
    http://download.chinaitlab.com/soft/10565.htm

    JBuilder速成資料
    http://download.chinaitlab.com/soft/9714.htm

    Jbuilder7和weblogic7整合開發(fā)手
    http://download.chinaitlab.com/soft/9664.htm

    JBUILDER9 軟件開發(fā)項目實踐
    http://download.chinaitlab.com/soft/9089.htm

    JbuilderX開發(fā)指南
    http://download.chinaitlab.com/soft/9088.htm

    Jbuilder x 指南
    http://download.chinaitlab.com/soft/7984.htm

    JBuilder4開發(fā)人員指南
    http://download.chinaitlab.com/soft/5939.htm

    JBuilder7 Weblogic7整和開發(fā)培訓手冊
    http://download.chinaitlab.com/soft/4727.htm

    JBuilder開發(fā)數據庫應用程序
    http://download.chinaitlab.com/soft/1701.htm

    Java開發(fā)指南--Servlets和JSP篇
    http://download.chinaitlab.com/soft/9793.htm

    Java Servlets 編程指南
    http://download.chinaitlab.com/soft/9098.htm

    Oreilly Java Servlet
    http://download.chinaitlab.com/soft/6522.htm

    Java Servlet開發(fā)與實例
    http://download.chinaitlab.com/soft/6029.htm

    深入Java Servlet 網絡編程
    http://download.chinaitlab.com/soft/9783.htm

    用JSP_Servlet構建三層式管理信息系統(tǒng)
    http://download.chinaitlab.com/soft/6034.htm

    Java Servlet幫助文檔
    http://download.chinaitlab.com/soft/2981.htm

    JSP網站編程教程
    http://download.chinaitlab.com/soft/11256.htm

    JSP語法分析
    http://download.chinaitlab.com/soft/11257.htm

    JSP實用教程
    http://download.chinaitlab.com/soft/10792.htm

    JSP語法(1)--HTML注釋
    http://download.chinaitlab.com/soft/10790.htm

    JSP應用開發(fā)詳解
    http://download.chinaitlab.com/soft/10025.htm

    JSP技術揭秘
    http://download.chinaitlab.com/soft/9387.htm

    JSP技術大全
    http://download.chinaitlab.com/soft/9388.htm

    JSP網上書店實例詳解
    http://download.chinaitlab.com/soft/9386.htm

    JSP動態(tài)網頁新技術
    http://download.chinaitlab.com/soft/8920.htm

    JSP 技術大全
    http://download.chinaitlab.com/soft/7782.htm

    JSP高級開發(fā)與應用
    http://download.chinaitlab.com/soft/7633.htm

    JSP 完全探索
    http://download.chinaitlab.com/soft/7546.htm

    JSP 高級開發(fā)與應用
    http://download.chinaitlab.com/soft/7116.htm

    JSP編程技巧
    http://download.chinaitlab.com/soft/7114.htm

    JSP速成教程
    http://download.chinaitlab.com/soft/6882.htm

    JSP網絡編程技術
    http://download.chinaitlab.com/soft/6880.htm

    JSP程序設計指南
    http://download.chinaitlab.com/soft/6690.htm

    最新JSP入門與應用
    http://download.chinaitlab.com/soft/6697.htm

    JSP快速入門
    http://download.chinaitlab.com/soft/6636.htm

    JSP網頁編程
    http://download.chinaitlab.com/soft/6527.htm

    JSP 實用教程
    http://download.chinaitlab.com/soft/6334.htm

    JSP入門與提高
    http://download.chinaitlab.com/soft/6326.htm

    JSP語法
    http://download.chinaitlab.com/soft/6116.htm

    掌握自定義JSP標簽
    http://download.chinaitlab.com/soft/6096.htm

    JSP 動態(tài)網站技術入門與提高
    http://download.chinaitlab.com/soft/6019.htm

    JSP實例入門
    http://download.chinaitlab.com/soft/4377.htm

    JSP教程之與數據庫通信
    http://download.chinaitlab.com/soft/3673.htm

    如何成為優(yōu)秀的JSP 程序員
    http://download.chinaitlab.com/soft/3002.htm

    JSP數據庫編程指南
    http://download.chinaitlab.com/soft/2946.htm

    JSP 高級編程
    http://download.chinaitlab.com/soft/2635.htm

    JSP實用編程實例集錦
    http://download.chinaitlab.com/soft/2154.htm

    JSP程序設計精彩實例
    http://download.chinaitlab.com/soft/2151.htm

    JSP即時應用
    http://download.chinaitlab.com/soft/1547.htm

    JSP程序設計精彩實例
    http://download.chinaitlab.com/soft/1543.htm

    JSP實用編程實例集錦
    http://download.chinaitlab.com/soft/1537.htm

    JSP基礎
    http://download.chinaitlab.com/soft/894.htm

    Eclipse開發(fā)Servlet及JSP:

    Eclipse+Tomcat集成開發(fā)servle
    http://download.chinaitlab.com/soft/6134.htm

    J2EE Jboss Ejb With Eclipse 2003
    http://download.chinaitlab.com/soft/6045.htm
    posted @ 2006-03-21 07:27 konhon 優(yōu)華 閱讀(2012) | 評論 (0)編輯 收藏

    僅列出標題
    共21頁: First 上一頁 4 5 6 7 8 9 10 11 12 下一頁 Last 
    主站蜘蛛池模板: 国产精品免费观看调教网| 国产精品亚洲美女久久久| 91成人免费福利网站在线| 亚洲美国产亚洲AV| 亚洲春色在线观看| 久久久久亚洲AV无码网站| 免费在线观看日韩| 最近免费中文字幕大全| 国产成人yy免费视频| 国产一区二区三区免费| 国产99精品一区二区三区免费| 亚洲国产精品无码久久| 国产中文字幕免费观看| 香蕉免费在线视频| 免费精品久久久久久中文字幕| 亚洲精品永久在线观看| 亚洲成年网站在线观看| 亚洲三级视频在线| 亚洲中文字幕丝袜制服一区| 日韩免费观看的一级毛片| 在线观看片免费人成视频无码| 免费又黄又爽又猛大片午夜| 豆国产96在线|亚洲| 亚洲av日韩综合一区二区三区| 亚洲娇小性色xxxx| 亚洲а∨天堂久久精品9966 | 黄床大片30分钟免费看| 亚洲人成网站在线在线观看| 中文字幕亚洲码在线| 99久久国产亚洲综合精品| 亚洲免费综合色在线视频| 亚洲欧美日韩中文二区| 亚洲精品久久无码| 狠狠入ady亚洲精品| 国产亚洲综合久久| 日本一区二区在线免费观看| 草久免费在线观看网站| 一级a性色生活片久久无少妇一级婬片免费放 | 亚洲中文字幕无码av在线| 亚洲一区免费在线观看| 亚洲精品456人成在线|