zoukankan      html  css  js  c++  java
  • JAVAF访问LOTUS对象

    使用 Java 可以访问 Domino 中的对象,如数据库、视图、文档等。本文简述了用 Java 访问 Domino 对象的基本编程方法。本文中的内容主要是根据 Lotus Domino/Notes 6 编写的,使用 R5 时会略有不同。

    Java 对 Domino 对象的访问是通过调用 lotus.domino 包来进行的。在运行环境中,lotus.domino 包中的接口是通过两个包来实现的:

    • lotus.domino.local - 支持从Notes/Domino所在的计算机上进行的本地调用
    • lotus.domino.cso - 支持对 Domino 服务器进行远程连接

    对于本地连接,Java 程序将在Notes客户端或Domino服务器所在的计算机运行,使用JNI 对Notes/Domino的代码进行访问。

    对于远程连接,Java 程序通过 CORBA 访问 Domino 所提供的服务。远程访问包括两个过程:

    • 客户端通过 HTTP 协议获得服务器的初始对象,作为 IOR (Interoperable Object Reference)
    • 客户端通过 IIOP 协议进一步获得服务器上的其他对象。

    在 lotus.domino 中,NotesFactory 类提供了 createSession 以及其他方法,可以用来开始 Java 应用程序或 servlet 对 Domino 对象的访问。不同的调用方式决定了访问是本地的还是远程的。

    要使用 lotus.domino 包来编译 Java 程序,类路径(classpath)中必须包含 Notes.jar (本地)或 NCSO.jar (远程)。例如:

    set classpath=%classpath%;c:\lotus\domino\Notes.jar

    或者

    set classpath=%classpath%;c:\lotus\domino\data\domino\java\NCSO.jar

    其中Notes.jar可以在Notes/Domino安装的程序目录中找到。NCSO.jar 在Domino服务器或Domino Designer的数据目录下,domino\java 子目录中。

    本地调用

    使用 createSession 时,没有参数、第一个参数为 null、或第一个参数为空字符串都表示本地调用。以下代码是等价的:

    Session s = NotesFactory.createSession() Session s = NotesFactory.createSession((String)null) Session s = NotesFactory.createSession("")

    要从应用程序和 servlet 中执行本地调用,路径(path)中必须包含 Notes/Domino 的程序目录,类路径(classpath)中必须包含 Notes.jar。例如,当 Domino 安装在"c:\lotus\domino"中时:

    set path := %path%;c:\lotus\domino
    set classpath := %classpath%;c:\lotus\domino\Notes.jar
    Notes.jar中包含 lotus.domino 和 lotus.domino.local 包。

    本地调用要求使用 NotesThread 类来管理线程。NotesThread 类扩展了 java.lang.Thread,包含了专门针对 Domino 的的初始化和终止代码。您可以有三种不同方式来使用它:

    • 通过继承来执行线程
    • 通过 Runnable 接口来执行线程
    • 通过静态方法来执行线程

    通过继承来执行线程

    要通过继承来执行线程,需要扩展 NotesThread(而不是 Thread),包含 runNotes 方法(而不是 run 方法)。NotesThread 线程可以和其他线程一样通过 start 方法来启动。这种方式较为易用,也比较不容易出错。

    import lotus.domino.*;
    public class myClass extends NotesThread
    {
       public static void main(String argv[])
       {
           myClass t = new myClass();
           t.start();
       }
       public void runNotes() // entry point for Notes thread
       {
           Try
           {
               Session s = NotesFactory.createSession();
               // Operational code goes here
           }
           catch (Exception e)
           {
               e.printStackTrace();
           }
       }
    }

    通过 Runnable 接口来执行线程

    要通过 Runnable 接口来执行线程,需要实现 Runnable 并包含 run 方法,这和其他使用线程的类完全一样。当您需要扩展其他类,不能扩展 NotesThread 类时可以使用这种方式。

    import lotus.domino.*;
    public class myClass implements Runnable
    {
       public static void main(String argv[])
       {
           myClass t = new myClass();
           NotesThread nt = new NotesThread((Runnable)t);
           nt.start();
       }
       public void run() // entry point for thread
       {
           try
           {
               Session s = NotesFactory.createSession();
               // Operational code goes here
            }
           catch (Exception e)
           {
               e.printStackTrace();
           }
       }
    }

    通过静态方法来执行线程

    要通过静态方法来执行线程,需要调用 sinitThread() 来初始化线程,调用 stermThread() 来结束线程。stermThread() 的调用必须与 sinitThread() 的调用严格一一对应。推荐将 stermThread() 放在"finally"程序块里。静态方法适用于不可能进行继承,或需要控制事件驱动的线程时。

    import lotus.domino.*;
    public class myClass
    {
       public static void main(String argv[])
       {
           try
           {
               NotesThread.sinitThread(); // start thread
               Session s = NotesFactory.createSession();
               // Operational code goes here
           }
           catch(Exception e)
           {
               e.printStackTrace();
           }
               finally
               {
                   NotesThread.stermThread(); // must terminate every thread
               }
       }
    }

    进行本地调用的每个线程都必须初始化一个 NotesThread 对象。它包含了访问 Domino 对象的 AWT 线程。侦听线程必须使用静态方法,因为它们不可能从 NotesThread 继承。

    既进行本地调用又进行远程调用的应用程序可以动态地决定何时使用静态方法 sinitThread 和 stermThread。当一个本地线程运行时,也可以进行远程调用。但不要将一个会话中得到的对象用于其他会话的调用。

    应该尽量避免多线程的使用,除非有非常充分的理由。要遵循以下原则:

    • 在同一会话(session)中不同线程(thread)之间,Domino 的对象会被自动共享、同步以及回收。如果每个线程使用不同的会话,这些功能就失去了,必须明确地在每个线程中管理对象的同步和回收。
    • 不要跨线程使用DbDirectory。 ?在多线程中访问同一个已有的文档是允许的,但只在一个线程中进行访问将简化内存管理。如果将对已有文档的访问限制在一个线程里,可以不检查其他线程就进行回收(recycle)。在多线程中创建新文档总是安全的,所使用的对象可以不管其他线程的状态就进行回收(recycle)。
    • 简要表文档是按线程来缓存的。当多个线程都要更新同一简要表文档时,会保存最后进行更新的线程所做的修改。
    • 删除文档时要特别注意,因为其他线程可能需要此文档以遍历视图或文档集合。
    • 当子对象被用于其他线程时,父线程要等所有子线程结束后再结束。当在 AWT 事件处理器中使用 Domino 对象时这一点要特别注意。

    远程调用

    调用createSession时,第一个参数使用非空的字符串,就表示所进行的是远程调用。第一个参数表示的是 Domino 服务器所在的计算机。例如:

    Session s = NotesFactory.createSession("myhost.east.acme.com")

    或者

    Session s = NotesFactory.createSession("myhost.east.acme.com:63148")

    后边的例子中指定了端口号,这样Domino服务器上就不需要启动 Web 服务了。详细信息见本文后面的"获取IOR"部分。

    要从应用程序或 servlet 中执行远程调用,运行程序的计算机的类路径里必须包括 NCSO.jar。 NCSO.jar 中包含 lotus.domino 包,lotus.domino.cso 包,lotus.domino.corba 包,以及 ORB 类。对于已安装的 Domino Designer 和 Domino 服务器,NCSO.jar 在 Domino 数据目录下的 domino\java 子目录中。如果计算机上没有安装 Domino 软件,必须手工将此文件从其他计算机上复制过来。 类路径中必须包含NCSO.jar,例如:

    set classpath := %classpath%;c:\lotus\domino\data\domino\java\NCSO.jar

    编程

    远程调用时不使用 NotesThread,只需要在 createSession 中指定主机名和端口号(可选)。

    不使用线程时,程序大致上是以下格式:

    import lotus.domino.*;
    public class myClass
    {
       public static void main(String argv[])
       {
           try
           {
               String host = "myhost.east.acme.com:63148";
               Session s = NotesFactory.createSession(host);
               // Operational code goes here
           }
           catch(Exception e)
           {
               e.printStackTrace();
           }
       }
    }

    使用线程时,程序为:

    import lotus.domino.*;
    public class myClass implements Runnable
    {
       public static void main(String argv[])
       {
           myClass t = new myClass();
           Thread nt = new Thread((Runnable)t);
           nt.start();
       }
       public void run()
       {
           try
           {
               String host = "myhost.east.acme.com:63148";
               Session s = NotesFactory.createSession(host);
               // Operational code goes here
           }
           catch(Exception e)
           {
               e.printStackTrace();
           }
       }
    }

    管理

    远程访问 Domino 时还需要对服务器进行一些配置。运行 Domino 的计算机必须可以通过 TCP/IP 协议进行访问。在计算机的网络设置中,需要检查 TCP/IP 属性中主机名和域名的设置。必须能够从客户端的计算机 ping 到 Domino 服务器的 Internet 名称。例如,服务器的主机名是 myhost,域名是 east.acme.com,则服务器的 Internet 名称是 myhost.east.acme.com。以下命令必须能够得到有效的回应:

    > ping myhost.east.acme.com

    在 Domino 目录(names.nsf)中,服务器文档的"全限定的 Internet 主机名"域中必须输入上述 Internet 名称。

    如图:

    服务器文档

    在本文前面的编程的例子中,服务器的 Internet 名称被用于 createSession 的第一个参数。这里也可以使用服务器的 IP 地址。

    要进行远程访问,在 Domino 服务器上,DIIOP 任务必须启动。HTTP 任务也可能需要启动,这取决于程序获取 IOR 的方式。要确认HTTP和DIIOP所使用的端口号,可以打开 Domino 目录中的服务器文档,进入"端口"下面的"Internet 端口",在 Web 标签和 DIIOP 标签下可以看到当前使用的端口号。缺省情况下,HTTP 的端口号是 80,DIIOP 的端口号是 63148。

    如果不知道要访问的数据库的名称,(例如要使用 .getFirstDatabase),必须有浏览数据库的权限。可以在"Internet 协议"-"HTTP"标签下设置这个权限,将"允许HTTP客户浏览数据库"设为"是"。

    要确保服务器上启动了 HTTP 和 DIIOP 任务,可以将它们加到 Notes.ini 文件中 ServerTasks 参数里。例如,Notes.ini 中应该有类似这样的一行:

    ServerTasks=Update,Replica,Router,AMgr,AdminP,CalConn,Sched,DIIOP,HTTP,
    LDAP

    如果服务器已启动,可以用以下控制台命令启动这两个任务:

    > load http
    > load diiop

    也可以用以下控制台命令停止这两个任务:

    > tell http quit
    > tell diiop quit

    用此命令可以更新 DIIOP 任务的设置:

    > tell diiop refresh

    用此命令可以重新启动 HTTP 任务:

    > tell http restart

    获取 IOR

    在 Domino 服务器上,IOR 是一个名为 diiop_ior.txt 的文件,它位于 Domino 数据目录下的 domino\html 子目录中。IOR 是一个编码的字符串,包含对服务器的 CORBA 访问的识别信息。客户端会将 IOR 字符串解码,并用它来建立远程连接。

    缺省情况下,远程客户端通过 Web 服务来请求 IOR ,然后通过 DIIOP 端口进行会话请求。这两个请求可以分开进行。 例如:

    String ior = NotesFactory.getIOR("myhost.east.acme.com"); // Get IOR using Web server port
    Session s = NotesFactory.createSessionWithIOR(ior); // Create session using DIIOP port

    等价于:
    Session s = NotesFactory.createSession("myhost.east.acme.com");

    在 NotesFactory 的调用中,可以在主机名后面加上冒号和端口号来指定用于获取 IOR 的端口。通过这样的机制,可以通过 DIIOP 端口来获取 IOR ,而不通过 HTTP 端口。例如:

    String ior = NotesFactory.getIOR("myhost.east.acme.com:63148"); // Get IOR using DIIOP port
    Session s = NotesFactory.createSessionWithIOR(ior); // Create session using DIIOP port

    也可以简化为:

    Session s = NotesFactory.createSession("myhost.east.acme.com:63148");

    注意不可以使用 DIIOP 端口来获取除 diiop_ior.txt 以外的的其他文件。

    如果通过 Web 服务端口来获取 IOR,Web 服务必须允许匿名访问。打开服务器文档,在"端口"-"Internet 端口"-"Web"标签下,"匿名"的验证选项要设置为"是"。

    通过 DIIOP 端口获取 IOR 是 Notes/Domino 6 的新功能。这样可以不必允许对 HTTP 服务的匿名访问,甚至不必启动 HTTP 服务。

    也可以通过其他方法获取 IOR,然后使用 createSessoinWithIOR。例如,可以直接将 diiop_ior.txt 文件从服务器的计算机上拷贝到客户端的计算机上。如果客户端上已经有了有效的 diiop_ior.txt,可以用以下代码与服务器建立远程连接:

    import lotus.domino.*;
    import java.io.*;
    public class platformior
    {
       public static void main(String argv[])
       {
           try
           {
               FileInputStream fin = new FileInputStream("c:\\Lotus\\NotesR6\\diiop_ior.txt");
               InputStreamReader fisr = new InputStreamReader(fin);
               BufferedReader br = new BufferedReader(fisr);
               String ior = br.readLine();
               fin.close();
               Session s = NotesFactory.createSessionWithIOR(ior);
               //Operational code goes here
           }
           catch(Exception e)
           {
               e.printStackTrace();
           }
       }
    }

    注意 IOR 可能会改变。以下动作都会使原来的 diiop_ior.txt 无效:

    • 改变 DIIOP 端口号
    • 启用或禁用一个 DIIOP 端口
    • 改变服务器的 TCP/IP 地址

    最后一项可以通过以下方法避免:打开服务器文档,在"Internet 协议"-"DIIOP"标签下,在"主机名称/地址"域中指定服务器的 Internet 主机名。

    这强制了diiop_ior.txt使用主机名而不是 IP 地址。这样,只要主机名不改变,IOR 就不会改变。也可以通过 Notes.ini 参数 DIIOPIORHost 来强制使用主机名。

    diiop 设置

    访问控制

    客户端的程序可以得到什么存取级别取决于createSession 的使用方式和服务器/客户端的设置。访问控制是通过以下两种方式之一实现的:

    • Domino 目录中的用户名及其 Internet 口令。 这种方式对本地调用和远程调用都可以使用。对于本地调用,所访问的必须是 Domino 服务器。
    • 当前 Notes ID (Notes.ini 文件中 KeyFileName 参数所指定的 ID)

    这种方式只在进行本地调用时可以使用。程序所在的计算机上有 Notes 客户端或 Domino 服务器都可以。 通过 Domino 目录访问

    通过 Domino

    目录访问时,所使用的代码将决定是作为匿名用户还是 Domino 目录中已有的用户来访问。NotesFactory调用中,如果只指定了主机名,或使用空字符串作为用户名和口令,将以匿名用户的身份访问服务器。例如:

    Session s = NotesFactory.createSession("myhost.east.acme.com:63148");

    或者:

    Session s = NotesFactory.createSession("myhost.east.acme.com:63148", "", "");

    要以某个 Domino 用户的身份访问服务器,需要在参数2和参数3中分别指定用户名和 Internet 口令。用户名和口令必须与 Domino 目录中的某个个人文档匹配。例如:

    Session s = NotesFactory.createSession("myhost.east.acme.com:63148", "Jane Smith/East/Acme",

    "topS3cr3t");

    对 Domino 服务器进行本地调用时,主机名应为空: Session s = NotesFactory.createSession("", "Jane Smith/East/Acme", "topS3cr3t") 要进行匿名的本地调用,三个参数都应为空:

    Session s = NotesFactory.createSession("", "", "")

    进行本地调用时,服务器不一定要运行。 服务器文档中的设置决定了是否可以进行匿名或用户名/口令的访问。在服务器文档中,"端口"-"Internet 端口"-"DIIOP"标签下,验证选项与代码的关系如下表:

    验证选项与代码的关系如下表
    代码验证选项
    createSession(host, "", "")
                            createSession(host, name, password)
    匿名必须设为"是"才能访问服务器名称和口令必须设为"是"才能访问服务器

    对于名称和口令验证,名称必须是 Domino 目录中某个个人文档中的用户名,口令必须是此个人文档中的 Internet 口令。管理员还可以将"强制使用服务器访问设置"选项设为"是",以强制 DIIOP 的访问遵循服务器文档的安全性标签下的"服务器访问"设置。

    服务器文档中的以下域可以用来控制 Internet 会话的安全性。从本质上来说,本地或远程 Java 类创建的Internet 会话的访问权限等同于 Web 用户。

    服务器文档中的以下域可以用来控制 Internet 会话的安全性
    说明
    服务器访问权限
    访问服务器进行远程或本地调用的用户必须列在此域中
    禁止访问服务器如果用户被列在此域中,无论远程或本地连接都不能建立
    创建数据库和模板用后台方法能否创建新数据库和模板
    创建新复本用后台方法能否创建复本数据库
    创建主模板用后台方法能否创建主模板
    编程限制
    运行无限制的方法和操作列在此域中的用户可以在Domino服务器上运行受限制的Java方法*。 如果程序 所使用的用户没有列在此域中,则不能在Domino服务器上执行这些方法,例如 访问Domino服务器的文件系统等,但仍可以在程序所在的计算机上执行各种方 法,包括访问本机的文件系统。
    签名将代表其他人运行的代理作为Web用户运行的代理将以Internet会话中的用户身份运行
    签名将代表代理的调用者运行的代理作为Web用户运行的代理将以Internet会话中的用户身份运行
    Internet 访问
    Internet 验证限制可以使用哪些名称作为用户名来登录

    * 哪些方法是受限制的请参考 Domino 6 Designer Help 中的"Restricted LotusScript and Java agent operations" 。

    服务器文档中"端口"-"Internet 端口"下,DIIOP 标签中的域的说明如下表:

    服务器文档中"端口"-"Internet 端口"下,DIIOP 标签中的域的说明
    说明
    (TCPI/IP)姓名和口令DIIOP 验证要求用户名和口令
    (TCP/IP)匿名 DIIOP验证不要求用户名和口令
    (SSL)姓名和口令DIIOP SSL 验证要求用户名和口令
    (SSL)匿名 DIIOP SSL 验证不要求用户名和口令
    强制使用服务器访问设置DIIOP是否强制使用安全性标签下的服务器访问设置

    以下notes.ini参数也会影响远程或本地Java 类建立的Internet会话的安全性:

    notes.ini参数也会影响远程或本地Java 类建立的Internet会话的安全性
    Notes.ini设置说明
    NoAmbiguousWebNamesNoAmbiguousWebNames=1时,如果用来登录DIIOP的用户名在$Users视图 中有多个匹配,则登录失败
    WebNameAuthenticWebNameAuthentic=1时,用来登录DIIOP的用户名应该是用户的全名
    NABWebLookupView设置NABWebLookupView="xxx",则Domino将在Domino 目录的"xxx"视图中 查找用来登录的用户名

    注意在数据库的存取控制表中,"Internet 用户的最大权限"设置也会对 Internet 会话的权限产生影响,DIIOP 的登录用户的权限不能超过此项设置。

    服务器大约每一个半小时刷新一次安全性的缓存。修改了安全性设置后,可以使用控制台命令"tell diiop refresh"来强制刷新。

    通过 Notes ID 访问

    要通过当前 Notes ID 访问服务器,在调用时应不指定任何参数:

    Session s = NotesFactory.createSession()

    在这种情况下,如果需要验证(如打开数据库时),会弹出一个对话框,提示输入Notes ID的口令。所使用的Notes ID是在搜索路径中能找到的第一个Notes.ini文件中,KeyFileName变量指定的。例如,Notes.ini 中有以下参数时,程序将使用 admin.id 来访问服务器:

    KeyFileName=admin.id

    必须输入该ID的口令,或按"取消",程序才能继续执行。 也可以将第二个参数指定为"(String)null",在第三个参数中指定该Notes ID的口令:

    Session s = NotesFactory.createSession((String)null, (String)null, "tops3cr3t")

    在服务器上,以上方法会按读者域限制访问,要进行完全的访问,可以用以下方法:

    Session s = NotesFactory.createSessionWithFullAccess()

    或者

    Session s = NotesFactory.createSessionWithFullAccess("tops3cr3t")

    结论

    您现在了解了用Java应用程序对Domino对象进行本地调用和远程调用的基本方法。关于较复杂的访问方式,如SSL加密,servlet,连接池,单一登录,防火墙,超时控制,资源回收及问题诊断,请参考以下文章:

    http://www-10.lotus.com/ldd/today.nsf/lookup/Java_access_2 (美国)

  • 相关阅读:
    SpringBoot之采用AOP统一打印日志信息
    SpringBoot之SpringBoot整合log4j
    SpringBoot之SpringBoot整合logback
    SpringBoot之SpringBoot整合多环境不同配置文件
    SpringBoot之SpringBoot整合devtools热部署
    [bug] Flask:jinja2.exceptions.UndefinedError: 'None' has no attribute 'id'
    [bug] Python:“TabError: inconsistent use of tabs and spaces in indentation”
    [bug] MySQL 无法删除表
    [bug] Flask css 不更新
    [bug] flink on yarn 启动失败
  • 原文地址:https://www.cnblogs.com/hannover/p/2618809.html
Copyright © 2011-2022 走看看