本文是由兩部分組成的系列文章的第 2 部分:本文將介紹使用 Domino Objects 開(kāi)發(fā) Java 應用程序中涉及的一些高級主題,其中包括 SSL 加密、servlet、連接池、單點(diǎn)登錄、會(huì )話(huà)超時(shí)和回收,本文還給出了一些故障檢修技術(shù)。
本文是由兩部分組成的系列文章的第 2 部分。在本系列文章的 第 1 部分中,您了解了本地和遠程地從 Java 應用程序使用 Domino Objects 的一些基礎知識。本文中您將了解 SSL 加密、servlet、連接池、單點(diǎn)登錄、會(huì )話(huà)超時(shí)和回收。文中還包括關(guān)于故障檢修的一個(gè)部分。本文假設您熟悉 Domino Java API,并已經(jīng)閱讀了第一篇文章。
SSL 加密
本系列文章的前一篇文章討論了在本地或遠程運行 Java 應用程序。遠程調用需要 HTTP 和 DIIOP 訪(fǎng)問(wèn)權??梢允褂?SSL (Secure Sockets Layer) 對通過(guò) DIIOP 端口的傳輸進(jìn)行加密。有關(guān)如何設置 DIIOP 的說(shuō)明,請參閱前一篇文章??蛻?hù)機代碼通過(guò)在 createSession 調用中指定新的第二個(gè)參數來(lái)表明加密要求。該參數是一個(gè) String 數組,第一個(gè)元素將 -ORBEnableSSLSecurity 作為其值,例如:
|
仍然使用非 SSL 端口(上例中為 63148)來(lái)獲得 IOR。實(shí)際服務(wù)請求是通過(guò) DIIOP SSL 端口進(jìn)行的,默認情況下,該端口為 63149。
運行代碼之前,必須設置有一個(gè)從證書(shū)權威機構獲得的通用受信任的根證書(shū)的服務(wù)器和客戶(hù)機。最好將這個(gè)過(guò)程分為一系列的步驟來(lái)講述。
步驟 1
創(chuàng )建密鑰環(huán)(key ring)。打開(kāi) Domino 服務(wù)器中的 Server Certificate Admin (certsrv.nsf) 數據庫,使用其表單創(chuàng )建和填充密鑰環(huán)。有關(guān)的詳細信息,請參閱 Administering the Domino System, Volume 2 或 Domino Administrator Help。為了進(jìn)行測試,可以使用 CertAdminCreateKeyringWithSelfCert 表單創(chuàng )建具有自我認證證書(shū)的密鑰環(huán)。
步驟 2
將密鑰環(huán)移至服務(wù)器。密鑰環(huán)包含密鑰環(huán)文件(KYR 文件)和存儲文件(STH 文件)。在訪(fǎng)問(wèn) Server Certificate Admin 數據庫的計算機上生成這些文件。將這兩個(gè)密鑰環(huán)文件移至或復制到包含 Domino 服務(wù)器的計算機上。將它們放在服務(wù)器的數據目錄中。例如,如果使用默認名稱(chēng)創(chuàng )建具有自我認證證書(shū)的密鑰環(huán),并將文件復制到服務(wù)器的數據文件安裝在 C:\Lotus\Domino\Data 中的計算機上,那么服務(wù)器文件將為:
C:\Lotus\Domino\Data\selfcert.kyr C:\Lotus\Domino\Data\selfcert.sth. 步驟 3
將 TrustedCerts.class 復制到客戶(hù)機中并將其放在類(lèi)路徑中。一旦密鑰環(huán)文件位于服務(wù)器中,啟動(dòng)或重新啟動(dòng) DIIOP 任務(wù)會(huì )在 Domino 數據目錄中生成名為 TrustedCerts.class 的文件。將該文件分布到任何計算機中,您將從這臺計算機使用 CORBA 通過(guò) SSL 訪(fǎng)問(wèn)服務(wù)器,并將包含該文件的目錄放在類(lèi)路徑中。例如,如果將文件復制到客戶(hù)機的 C:\Lotus\TrustedCerts.class 中,那么設置類(lèi)路徑將如下所示:
set classpath := %classpath%;c:\lotus 步驟 4
為服務(wù)器啟用 SSL。在服務(wù)器的 Domino Directory 的 Server 文檔中,轉至 Ports 選項卡,然后轉至 Internet Ports 選項卡。在 SSL 設置下,指定 SSL 密鑰文件名(例如,selfcert.kyr)。再轉至 DIIOP 選項卡。確保 SSL 端口號正確 —— 默認端口號為 63149。啟用 SSL 端口。并根據需要設置 Name & password 和 Anonymous 身份驗證。
Servlet
Domino 服務(wù)器 HTTP 任務(wù)通過(guò)加載 servlet 引擎和 JVM 來(lái)支持 servlet。在 Domino Directory 的 Server 文檔中,轉至 Internet Protocols 選項卡、Domino Web Engine 選項卡和 Java Servlets 選項卡進(jìn)行設置。Domino Designer Help 文檔“Running servlets in Domino”提供了一般情況的詳細說(shuō)明。下面是 Server 文檔上面部分的示例:

默認情況下,Domino 在 domino\servlet 下的數據目錄中查找 servlet 可執行代碼。例如,如果名為 domino\servlet 的文件中包含可執行 servlet,那么可以按如下所示將其存儲在服務(wù)器上:
c:\lotus\domino\data\domino\servlet\MyServlet.class 從瀏覽器(默認情況下),通過(guò)在 URL 中指定 /servlet 和類(lèi)文件的名稱(chēng)來(lái)運行 servlet。例如:
http://myhost.east.acme.com/servlet/MyServlet
如果正在訪(fǎng)問(wèn) Domino Objects,還有考慮其他兩點(diǎn)。首先,對于遠程訪(fǎng)問(wèn),服務(wù)器的 Notes.ini 文件必須為變量 JavaUserClasses 指定 NCSO 歸檔文件。該變量是由 HTTP 任務(wù)加載的 JVM 的類(lèi)路徑。典型規范應該為:
JavaUserClasses=c:\lotus\domino\data\domino\java\NCSO.jar 其次,在本地訪(fǎng)問(wèn) Domino Objects 的代碼必須使用 NotesThread。因為其他方法無(wú)法在 servlet 中使用,所以在使用任何 Domino Objects 之前先調用 NotesThread.sinitThread,然后調用 NotesThread.stermThread。下列代碼示范了在本地訪(fǎng)問(wèn) Domino Objects 的簡(jiǎn)單 servlet:
|
Java 類(lèi)的本地訪(fǎng)問(wèn)僅需要 HTTP。必須運行 HTTP 任務(wù),這樣瀏覽器才可以訪(fǎng)問(wèn)服務(wù)器,從而調用 servlet。無(wú)需使用 DIIOP 任務(wù)。對于遠程訪(fǎng)問(wèn),必須同時(shí)運行 DIIOP 任務(wù)。編碼將相對簡(jiǎn)單,因為不使用 NotesThread。極有可能您將不使用遠程類(lèi)從同一臺計算機訪(fǎng)問(wèn) Domino。首選是本地類(lèi)。然而,可以從不同計算機上運行的其他 servlet 管理器(例如,WebSphere)來(lái)使用遠程類(lèi)。下面是一個(gè)模板:
|
連接池
連接池允許使用同一 ORB (Object Reference Broker) 創(chuàng )建多個(gè)會(huì )話(huà),因為所有會(huì )話(huà)共享一個(gè) TCP/IP 連接,所以這將減少網(wǎng)絡(luò )資源。在 servlet 應用程序和服務(wù)器到服務(wù)器的應用程序中,連接池特別有用??梢允褂?NotesFactory createORB 方法之一生成 ORB。然后使用帶有 ORB 參數的 createSession 方法創(chuàng )建會(huì )話(huà)。
這里存在的危險是過(guò)度加載網(wǎng)絡(luò )連接?;ㄙM很長(cháng)時(shí)間的某一會(huì )話(huà)上的操作會(huì )妨礙共享 ORB 的其他會(huì )話(huà)上的操作。創(chuàng )建的會(huì )話(huà)數不要超過(guò)連接可以處理的數目,當完成一個(gè)會(huì )話(huà)時(shí)要對其進(jìn)行回收。
下列代碼是一個(gè)簡(jiǎn)單示例,該示例使用了一個(gè) ORB,以及多達 10 個(gè)的 Domino 會(huì )話(huà)。第一次運行 servlet 時(shí)以及每第十次運行 servlet 之后,servlet 都會(huì )創(chuàng )建新的 ORB。示例使用了下一節中將介紹的 SSO。
|
SSO(單點(diǎn)登錄)
單點(diǎn)登錄允許通過(guò)一臺服務(wù)器上的一次登錄,來(lái)訪(fǎng)問(wèn)多個(gè) Domino 和 WebSphere 服務(wù)器。訪(fǎng)問(wèn)的服務(wù)器必須像 Administering the Domino System, Volume 2 或 Domino Administrator 幫助中說(shuō)明的那樣設置了 SSO。您還可以參閱紅皮書(shū) Domino and WebSphere Together Second Edition 。
下列簽名在通過(guò) Domino 或 WebSphere 服務(wù)器的預先身份驗證之后創(chuàng )建了一個(gè) SSO 會(huì )話(huà)。
下列代碼說(shuō)明了基本知識。它使用名稱(chēng)和密碼訪(fǎng)問(wèn)服務(wù)器,獲得 SSO 令牌,然后使用該令牌訪(fǎng)問(wèn)同一 SSO 域中的其他服務(wù)器。
|
接下來(lái)的代碼是一個(gè) servlet 示例,從 HTTP cookie 列表中取得 SSO 令牌。
|
會(huì )話(huà)超時(shí)
對于遠程會(huì )話(huà),服務(wù)器都會(huì )有最大空閑時(shí)間的限制。如果一個(gè)會(huì )話(huà)的空閑時(shí)間超過(guò)這個(gè)限制,服務(wù)器將中止此會(huì )話(huà)并釋放資源。在 Server 文檔里,可以在 Internet Protocols -〉DIIOP 標簽的 Idle session timeout 域里設置這個(gè)值,默認值是 60 分鐘。

在客戶(hù)端代碼里,使用 Session.isValid() 方法來(lái)判斷一個(gè)遠程會(huì )話(huà)是否可用。如果遠程會(huì )話(huà)已經(jīng)超時(shí),isValid() 方法將返回 false 值。下面的例子將創(chuàng )建一個(gè)遠程會(huì )話(huà),然后重新訪(fǎng)問(wèn)此會(huì )話(huà)。在條件語(yǔ)句中將判斷這個(gè)會(huì )話(huà)是否仍然可用,如果不可用,程序將重新創(chuàng )建一個(gè)會(huì )話(huà)。
|
isValid() 方法將激活會(huì )話(huà),而該會(huì )話(huà)將重置超時(shí)時(shí)鐘。
回收
Java 不認識重量級后端 Domino Objects,僅認識表示這些對象的輕量級 Java 對象。對于本地類(lèi),Domino Objects 在運行 Java 程序的過(guò)程中使用了內存,如果不回收這些內存,就不會(huì )發(fā)生垃圾收集,直到程序退出。內存使用在下列情況下可能存在一些問(wèn)題:
所有 Domino Objects 都有回收方法?;厥辗椒▽⒔K止當前對象及其所有子對象,并釋放它們的內存。在內存使用可能存在問(wèn)題的時(shí)候,強烈建議對內存進(jìn)行回收。例如,可以將下列語(yǔ)句(其中會(huì )話(huà)是 Session 對象)放在 servlet 中 doGet 代碼的后面。這樣將在每次調用 servlet 后回收所有使用的 Domino Objects。
session.recycle(); 可以將下列語(yǔ)句放在處理文檔(其中 doc 是 Document 對象)的循環(huán)(在任何應用程序中)的后面。這樣將在每次調用時(shí)回收 Document 對象及其所有子對象(如 Item)。
doc.recycle(); 對于遠程 Domino Objects,回收沒(méi)有這樣重要。那時(shí)內存使用是在 DIIOP 過(guò)程中,由線(xiàn)程執行垃圾收集。如果失去 TCP/IP 連接,整個(gè)會(huì )話(huà)都將被自動(dòng)回收。
回收也有下列簽名:
recycle(java.util.Vector objects) 其中 vector 包含 Domino Objects。該簽名有效地對回收請求進(jìn)行批處理,提高遠程調用的效率。
在進(jìn)行回收時(shí),請遵守下列指導原則:
故障檢修
下一節將介紹一般問(wèn)題的故障檢修方案。
類(lèi)路徑和路徑
確保代碼可以訪(fǎng)問(wèn)必需的類(lèi)。假設 Notes 和 Domino 軟件安裝在 c:\lotus\domino 中,那么類(lèi)路徑和路徑必須按如下所示方式進(jìn)行設置:
| 環(huán)境 | 類(lèi)路徑 | 路徑 |
| 本地應用程序或 servlet | c:\lotus\domino\Notes.jar | c:\lotus\domino |
| 遠程應用程序或 servlet | c:\lotus\domino\data\domino\java\NCSO.jar | 不適用 |
對于本地類(lèi)來(lái)說(shuō),PATH 是重要的,因為 Notes.jar 需要使用 Notes/Domino 二進(jìn)制文件和 Notes.ini。
如果從沒(méi)有 Domino 軟件的計算機遠程訪(fǎng)問(wèn) Domino,必須將 NCSO 歸檔文件復制到該計算機中。類(lèi)路徑應該反映歸檔文件在該計算機中的位置。
對于 SSL,類(lèi)路徑必須指定包含 TrustedCerts.class 的文件夾。
遠程計算機
要遠程使用 Domino Objects,必須運行遠程計算機,必須運行 Domino 服務(wù)器,客戶(hù)機計算機必須使用正確的主機名稱(chēng)或 IP 地址。
在 Windows 中,如果有權訪(fǎng)問(wèn)服務(wù)器計算機,可以通過(guò)下列 DOS 命令獲取諸如主機名稱(chēng)、DNS 服務(wù)器和 IP 地址之類(lèi)的信息:
> ipconfig/all 在客戶(hù)機計算機中,必須能夠訪(fǎng)問(wèn)服務(wù)器計算機??梢試L試 ping 命令:
> ping hostname 或者
> ping ipaddress 如果無(wú)法 ping 遠程計算機,那么是網(wǎng)絡(luò )有問(wèn)題??赡苁俏锢砭W(wǎng)絡(luò )連接、網(wǎng)絡(luò )設置或輸入的名稱(chēng)存在問(wèn)題。必須解決這些問(wèn)題,才能繼續進(jìn)行后面的操作。
如果可以 ping 遠程計算機,嘗試 telnet 命令來(lái)查看遠程計算機監聽(tīng)的端口是否正確。對于 HTTP,默認端口是 80,對于 DIIOP,默認端口為 63148。
> telnet host port 如果能夠 ping 計算機,但不能 telnet 端口,那么可能是發(fā)生了下列情況之一:
如果通過(guò) Web 服務(wù)器端口訪(fǎng)問(wèn) IOR,應該能夠使用下列 URL 從瀏覽器訪(fǎng)問(wèn) Domino Server:
http://hostname 應該能夠使用下列 URL 查看 IOR 文件:
http://hostname:port/diiop_ior.txt 如果有權訪(fǎng)問(wèn) Domino Server,可以使用下列控制臺命令檢查 DIIOP 任務(wù):
> tell diiop show config 下面是一些典型輸出:
|
錯誤消息
下面是一些錯誤消息和可能的解釋。
HTTP JVM java.lang.ClassNotFoundException and HTTP JVM java.lang.NoClassDefFoundError
這些消息顯示在服務(wù)器控制臺上。它們指明客戶(hù)機正在嘗試使用遠程類(lèi),但未在服務(wù)器中的 Notes.ini 中指定該 JavaUserClasses。
NotesException: Could not get IOR from Domino Server: java.net.ConnectException: Connection refused
該錯誤消息指出存在下列情況之一:
NotesException: Could not get IOR from Domino Server: java.net.ConnectException: Operation timed out
在條錯誤消息指出存在網(wǎng)絡(luò )配置錯誤。
NotesException: Could not get IOR from Domino Server: java.net.UnknownHostException
這條錯誤消息指出存在下列情況之一:
NotesException: Could not open Notes session: org.omg.CORBA.COMM_FAILURE: java.net.ConnectException: Connection refused
這條錯誤消息指出您未在服務(wù)器上運行 DIIOP 任務(wù)。
NotesException: Invalid user name/password
這條錯誤消息指出代碼嘗試使用未知名稱(chēng)或無(wú)效密碼訪(fǎng)問(wèn) Domino Directory。
NotesException: Server access denied
這條錯誤消息指出進(jìn)行了 Anonymous 訪(fǎng)問(wèn),但未被允許。
NotesException: User username is not a server
這條錯誤消息指出嘗試通過(guò)客戶(hù)機上的 Domino Directory 來(lái)運行會(huì )話(huà)。
NotesException: Wrong Password
這條錯誤消息指出在嘗試通過(guò) Notes ID 訪(fǎng)問(wèn)時(shí),代碼提供了錯誤密碼。如果代碼不發(fā)送密碼,訪(fǎng)問(wèn)最初為 Anonymous。如果需要身份驗證(例如,試圖打開(kāi)數據庫),會(huì )出現 Lotus Notes 框來(lái)要求您輸入密碼。該框會(huì )一直顯示,直到用戶(hù)提供了正確的密碼或單擊 Cancel 為止。
Reference to createSession is ambigous
在編譯過(guò)程中會(huì )出現這種錯誤消息。表明使用了 null 作為 createSession 參數。在大多數情況下,必須使用“(String)null”。
UnsatisfiedLinkError: NCreateSession
該錯誤消息指明本地會(huì )話(huà)未使用 NotesThread。提供 NotesThread.sinitThread 和 stermThread,或者使用 NotesThread。
NotesFactory 簽名
NotesFactory createSession 方法可以創(chuàng )建本地或遠程會(huì )話(huà)對象??梢允褂?Notes ID 或 Domino Directory 進(jìn)行本地會(huì )話(huà)調用。遠程會(huì )話(huà)使用 Domino Directory。
對于遵守下列格式的 NotesFactory 簽名:
hostname = hostname | hostname:port | ipaddress | ipaddress:port |
|
|
Notes.ini 變量
下列 Domino 服務(wù)器的 Notes.ini 變量會(huì )影響 DIIOP 任務(wù)。
| 變量 | 描述 |
| DIIOPConfigUpdateInterval | 指定 DIIOP 應該檢查的時(shí)間,以刷新它在 Domino Directory 中的配置數據,以分鐘表示。默認值為 3 分鐘 |
| DIIOPDNSLookup | 確定 DIIOP 是否應該為連接和使用 DIIOP 服務(wù)的每個(gè)客戶(hù)機進(jìn)行 DNS 名稱(chēng)查找: 1 —— 啟用 DNS 查找 2 ——(默認)禁用 DNS 查找 當使用服務(wù)器控制臺顯示任務(wù)時(shí),可以看到這條信息 |
| DIIOPIORHost | 指定主機名稱(chēng)或 IP 地址,使用其通過(guò) DIIOP 識別服務(wù)器。默認名稱(chēng)基于 Server 文檔中 Basics 選項卡下“Fully qualified Internet host name”字段。設置該值的首選方法是使用 Server 文檔中 DIIOP 和 Internet Protocols 選項卡下的 Host name/Address 字段。 在 R5 中,該變量稱(chēng)為 DIIOP_IOR_HOST,但它對向后兼容仍然有效 |
| DIIOPIgnorePortLimits | (僅 Linux)確定是否忽略端口限制,從而可以使用默認 DIIOP 端口 63148 和 63149。一些 Linux 系統設置端口限制,不允許使用 DIIOP 通常的默認值: 1 —— 忽略限制;使用端口 63148 和 63149 2 —— 遵守限制;使用端口 60148 和 60149 在 R5 中,該變量稱(chēng)為 DIIOP_IGNORE_PORT_LIMITS,但它對向后兼容仍然有效。 |
| DIIOPLogLevel | 指定 DIIOP 向服務(wù)器控制臺和日志提供的信息的級別: 0 —— 僅顯示錯誤和警告 1 —— 還顯示信息消息 2 —— 還顯示會(huì )話(huà)初始化和終止消息 3 —— 還顯示會(huì )話(huà)統計信息 4 —— 還顯示事務(wù)消息 可以在服務(wù)器控制臺中使用 tell diiop log= n 命令設置該值 |
| DIIOPCookieCheckAddress | 對于與 Domino HTTP 服務(wù)器下載的 applet 一起使用的基于服務(wù)器的 cookie,該變量確定訪(fǎng)問(wèn) cookie 的客戶(hù)機的 IP 地址是否必須與接收 cookie 的客戶(hù)機的 IP 地址相匹配: 0 ——(默認)不必匹配 1 —— 必須匹配 大多數情況下,客戶(hù)機 IP 地址不必匹配。使用 HTTP 發(fā)出 cookie,HTTP 通常是通過(guò)代理服務(wù)器發(fā)送的。cookie 的用戶(hù)是 applet,而 applet 不通過(guò)代理服務(wù)器 |
| DIIOPCookieTimeout | 對于與 Domino HTTP 服務(wù)器下載的 applet 一起使用的基于服務(wù)器的 cookie,該變量指定每個(gè) cookie 有效的分鐘數。無(wú)法使用到期的 cookie 與 DIIOP 任務(wù)進(jìn)行會(huì )話(huà)。該變量的默認值為 10。最小值為 1 |
聯(lián)系客服