在 IBM Lotus Domino Designer 中使用 Java 构建应用程序

本文旨在帮助那些传统的 LotusScript 开发人员转向 Java 开发。在几乎不具备 Java 知识的情况下,本文可帮助您开始在 IBM Lotus Domino 中进行 Java 应用程序开发。

Oscar Hernandez, 高级软件工程师, IBM

Oscar I Hernandez 是 IBM Lotus 技术支持中心的高级软件工程师。他是 Lotus Notes/Domino 应用程序开发团队的成员,也是 IBM 认证的高级应用程序开发人员。



2009 年 10 月 14 日

简介

对于 IBM Lotus Notes 应用程序开发人员来说,LotusScript 和 LotusScript 类在设计 Notes 应用程序时很有用。LotusScript API 支持以编程方式与数据库、文档,甚至设计元素进行交互。随着 Java 发展成为主流编程语言,原来越多的 Notes 应用程序开发人员开始将目光投向 Java。

本文面向那些想要在 IBM Lotus Domino 中使用 Java 进行编程的 LotusScript 开发人员。假定读者具有一定的 LotusScript 编程经验。

本文包含三部分:Java 语言、示例和其他要素。Java 编程人员可以直接跳到示例部分,但是新手应该从 Java 语言部分开始阅读。


Java 语言

发布于 1995 年,Java 是一种面向对象的编程语言,它的出现满足了平台独立性需求。这是通过将 Java 源代码编译成字节码实现的,然后任意平台上的任何 Java 虚拟机(JVM)都可以解释字节码。

因此,只要为目标平台实现了 JVM,就可以运行任何 Java 应用程序。有关更多信息,请参见 “The History of Java Technology”。

Java 的语法类似于 C,而它面向对象的实现方式类似于 C++,因此 C/C++ 编程人员可以轻松掌握 Java。但是,LotusScript 开发人员可能会发现 Java 语法与 LotusScript 大不相同。

由于本文关注的是在 Lotus Domino 中使用 Java,因此所展示的示例也将在 Lotus Domino 的环境中实现。

我们从经典的 “Hello World” 示例开始。在 Domino Designer 中创建新的 Java 代理时,会收到表 1 左栏所示的模板代码。右栏的代码已经进行了修改以适应 “Hello World” 示例的需要。

表 1. Hello World 示例
模板 Java 代理代码Hello World Java 代理代码
 import lotus.domino.*; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext= 
                session.getAgentContext(); 
            
            // (Your code goes here) 

        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }
 import lotus.domino.*; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext= 
                session.getAgentContext(); 
            
            // (Your code goes here) 

            System.out.println("Hello World!"); 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

逐行详解

我们来逐行看一下这段代码:

import lotus.domino.*;

Java 使用 import 语句以包括其他 Java 类。在本例中,所有 lotus.domino 类对于代理代码都可用。Java 类通常包含在 JAR 文件中。代理可以通过几种方式使用 JAR 文件。有关 JAR 文件的信息,请参阅本文第 4 节 “将外部 JAR 文件与 Java 代理一起使用” 部分。

public class JavaAgent extends AgentBase {

Java 是一种面向对象的编程语言。该行证明了这一点,创建 Java 代理时,它创建了 JavaAgent 类,这是在其中编写 Java 代码的主类。

可能还注意到了 JavaAgent 类扩展了 AgentBase 类。因为 Java 是面向对象的,所以扩展 AgentBase 类为我们提供了进入代理的入口点,这将我们带到了下一行。

public void NotesMain() {

NotesMain 方法是到代理的入口点。这里我们用自己的定义改写了 AgentBase 方法定义。

try {

在 Java 中,错误处理通过 try 和 catch 块进行处理。Java 中抛出异常的方法必须囊括在 try 块中,而且每一个 try 块都必须有一个相应的 catch 块。在 “Hello World” 示例中需要 try 和 catch 块,因为 getAgentContext 方法抛出了 NotesException。要查看哪些 Domino 方法抛出异常,请参阅 Domino Designer 帮助文件中的方法签名。

Session session = getSessiono;

AgentBase 类的 getSession 方法用于创建会话对象。Java Session 类类似于 LotusScript NotesSession 类。

AgentContext agentContext = session.getAgentContexto;

AgentContext 类用于获取到当前数据库的句柄(使用其 getCurrentDatabase 方法)。在 LotusScript 中,不需要使用这个额外的类来获取到当前数据库的句柄。

//(Your code goes here)

这一行要注意的是单行注释以 “//” 开头。多行注释在开始和结尾处使用 “/*”(类似于 C++)。

System.out.println("Hello World!");

这是用于输出到控制台的 Java 方法。要在 Notes 中打开 Java 控制台,从菜单中选择 Tools > Show Java Debug Console。System.out.println 方法类似于 LotusScript Print 方法。

} catch(Exception e) {

这是与上文 try 代码块相对应的 catch 语句。

e. pri ntStackTraceo;

在 catch 代码块中,可以按照自己的意愿处理异常;在本例中,我们只是将其输出到堆栈跟踪。

Java 语言基础知识

Java 提供了 8 种基本类型:byte、short、int、long、char、float、double 和 Boolean。 表 2 介绍了每种类型并指出了相对应的 LotusScript 的等价物(如果有)。

表 2. 基本类型和 LotusScript 等价物
Java基本类型Java 说明LotusScript 等价物
byte正负 8 位二进制补码整数(-128 到 127)Byte
相似点:8 位
不同点:无负数(0 到 255)
short正负 16 位二进制补码整数(-32,768 到 32,767)Integer
相似点:16 位,有正负(-32,768 到 32,767)
int正负 32 位二进制补码整数(-2,147,483,648 到 2,147,483,647)Long
相似点:32 位,有正负(-2,147,483,648 到 2,147,483,647)
long正负 64 位二进制补码整数(-9,223,372,036,854,775,808 到
9,223,372,036,854,775,807)
N/A
char单个 16 位 Unicode 字符N/A
但是, LotusScript 提供了一个 String 类型,它包含多个字符
float单精度 32 位 IEEE 754 浮点Single
相似点:单精度 32 位浮点
double双精度 64 位 IEEE 754 浮点Double
相似点:双精度 64 位浮点
Booleantrue 或 false 值Boolean
相似点:true 或 false 值

运算符

Java 具有丰富的运算符集。表 3 只是显示了其运算符的一部分并提供了说明和 LotusScript 的等价物(如果有)。有关完整列表,请访问 Java 教程运算符页面

表 3. Java 运算符
Java 算术运算符说明LotusScript 等价物
=赋值=
~~
~~递增N/A
+=加法赋值N/A
­-减(也是一元减运算符)-
--递减N/A
-=减法赋值N/A
**
*=乘法赋值N/A
//
/=除法赋值N/A
%求余数Mod
%=求余数赋值N/A
Java 关系运算符说明LotusScript 等价物
==相等=
!=不等于<>, ><
>大于>
>=大于等于>=, =>
<小于<
<=小于等于<=, =<
Java 逻辑(位)运算符说明LotusScript 等价物
&按位与And
I按位或Or
A按位异或Xor
-按位求补Not
>>带有符号扩展的右移位N/A
<<左移位N/A
Java 逻辑(布尔)运算符说明LotusScript 等价物
&&布尔与And
II布尔或Or
==布尔等于Eqv
!布尔非Not

声明变量

Java 中声明变量的语法是类型,后面接着变量名:

类型 variable_name;

在 Java 中,变量名由字母、数字和下划线组成。变量名是区分大小写的并且不能以数字开头。

JavaLotusScript
int i;Dim i as Integer
String s;Dim s as String

创建函数

关于函数语法,LotusScript 和 Java 有两个主要的不同之处。首先,返回类型放在函数名前面(这与 LotusScript 相反,在 LotusScript 中返回类型放在末尾);第二,Java 使用返回关键字从函数返回值(请参见清单 1)。

清单 1. 创建函数示例
 return _type function_name(parameter_type 1 parameter_name 1, 
    parameter_type2 parameter_name2) 
 { 
 // 函数代码 ... 
 return return_type_object; 
 }
JavaLotusScript
 public int product(int x, int y) 
 { 
    return x*y; 
 }
 Function product(x As Integer, y As Integer) As Integer 
    product = x * y 
 End Function
Calling the function:
 int i = product(2,4); 
 System.out.println(i);
Calling the function:
 Dim i As Integer 
 i = product(2, 4) 
 Print i

创建类

Java 中创建类的语法与 LotusScript 中的类似。它们都使用带有 private/public 选项的类关键字,并且都支持类成员以及类方法。但是,需要注意 LotusScript 类构造方法使用 New 关键字,而 Java 使用无参数的类名称(请参见清单 2 和表 4)。

清单 2. 创建类示例
 class class_name 
 { 
    type class_member1; 
    type class_member2; 
    .... 
    
    class _name() 	 // 构造方法
    { 
        // 构造方法代码
    } 

    return _type class_method1 (parameter list) 
    { 
        // 方法代码
    } 
    
    return _type class_method2(parameter list) 
    { 
        // 方法代码
    } 
    .... 
    
 }
表 4. 创建类
JavaLotusScript
 public class Person 
 { 
    private String Name; 
    private int Age; 
    
	 public Person() 
    { 
        this.Name=""; 
        this.Age=0; 
    } 

    public void SetName(String name) 
    { 
        this.Name = name; 
    } 

    public String GetName() 
    { 
        return this.Name; 
    } 

    public void SetAge(int age) 
    { 
        this.Age = age; 
    } 

    public int GetAge() 
    { 
        return this.Age; 
    } 

    public void AddYears(int i) 
    { 
        this.Age = this.Age + i; 
    } 
 }
 Public Class Person 
    Private PName As String 
    Private PAge As Integer 
    
	 Sub New 
        PAge = 0 
        PName = ""
    End Sub 

    Public Property Set Person_Name As String 
        PName = Person_Name 
    End Property 

    Public Property Get Person_Name As String 
        Person_Name = PName 
    End Property 

    Public Property Set Age As Integer 
        PAge = Age 
    End Property 

    Public Property Get Age As Integer 
        Age = PAge 
    End Property 

    Sub AddYears (i As Integer) 
        PAge = PAge + i 
    End Sub 

 End Class

创建类的实例 :

 Person p = new Person(); 
 p.SetName("John Doe"); 
 p.SetAge(20); 
 System.out.println(p.GetName() + " " +p.GetAge()); 
 p.AddYears(5); 
 System.out.println(p.GetName() + " " +p.GetAge());

创建类的实例 :

 Dim p As New Person 
 p.Person_Name = "John Doe"
 p.Age = 20 
 Messagebox p.Person_Name & " " & Cstr(p.Age) 
 p.AddYears(5) 
 Messagebox p.Person_Name & " " & Cstr(p.Age)

流控制语句

要控制脚本流动,Java 提供了您希望从编程语言中获得的所有标准流控制语句。表 5 列出了 Java 最常用的流控制语句及其 LotusScript 等价物。有关 Java 流控制语句的更多信息,请访问 Java 教程控制流语句页

表 5. Java 流控制语句
Java 流控制语句LotusScript 等价物
 if (condition) { 
    //perform these statements 
 }
 If condition Then 
    'perform these statements 
 End If
 if (condition) { 
    //perform these statements 
 } 
 else { 
    //perform these statements 
 }
 If condition Then 
    'perform these statements 
 Else 
    'perform these statements 
 End If
 switch (expr) { 
    case c1: 
        //perform these statements if expr == c1 
        break; 
    case c2: 
        //perform these statements if expr == c2 
        break; 
    . . . 
    default: 
        //perform these statements if 
        //expr != anyof cases 
 }
 Select Case expr 
    Case c1 
        'perform these statements if expr = c1 
    Case c2 
        'perform these statements if expr = c2 
    ... 
    Case Else 
        'perform these statements if 
        'expr <> anyof the cases 
 End Select
 while (condition) { 
    //perform these statements 
 }
 While condition 
    'perform these statements 
 Wend
 do { 
    //perform these statements 
 } while (condition);
 Do While condition 
    'perform these statements 
 Loop
 for (initialization; termination; increment) { 
    //perform these statements 
 }
 For countVar = first To last 
    'perform these statements 
 Next

LotusScript 与 Java 语言的不同之处

LotusScript 与 Java 的类似之处在于它们都是面向对象的编程语言。除语法外,两种语言之间一个主要不同是 Java 是强类型的,而 LotusScript 不是。

在 Java 中,必须在使用之前声明所有变量(名称和类型)。在 LotusScript 中没有这样的要求,尽管也有一些类型增强。

另一个主要不同是 Java 区分大小写,而 LotusScript 不区分。编写 Java 代码时要记住这一点,因为 p 和 P 是两个不同的变量,而 setName 和 SetName 是两个不同的方法。

特定于 Domino 的不同

尽管名称不同,但是大部分为 LotusScript 提供的 Domino 类在 Java 中都能找到。在 LotusScript 中,Domino 类以 “Notes” 开头;例如,用于处理数据库的类是 “NotesDatabase”,而针对文档的类是 “NotesDocument”。

另一方面,在 Java 中,类名称不以 “Notes” 开头。因此,处理数据库的类就是 “Database”,而针对文档的类是 “Document”。

LotusScript 与 Java Domino 类之间的主要不同是 UI 类。 LotusScript 提供了以下类,用于 UI 交互:

NotesU IWorkspace、NotesU I Database、NotesU I Document 和 NotesU IView

这些类使您能与 Notes 中当前打开的数据库、文档或视图进行交互。但是在 Java 中就没有等价的 UI 类。有关 Java Domino 类的完整列表,请参阅 Domino Designer 帮助文件


示例

我们来看一些使用 LotusScript 执行的常见任务,研究一下如何在 Java 中进行对等操作。第一个例子是发送电子邮件消息。

示例 1:发送电子邮件

花一分钟时间来研究一下下面清单 3 中的 LotusScript 代码:

清单 3. 示例 LotusScript 发送电子邮件代码
 1 	 Dim session As New NotesSession 
 2 	 Dim database As NotesDatabase 
 3 	 Dim email As NotesDocument 
 4 	 Dim sendto As String 
 5 	 Dim subject As String 
 6 	 Dim body As String 
 7 	 Set database = session.CurrentDatabase 
 8 	 Set email = database.CreateDocument 
 9 	 sendto = "Enter _Email _Address _Here"
 10 	 subject = "Email sent by LotusScript code"
 11 	 body = "Text in body of email sent by LotusScript code"
 12 	 Call email.ReplaceItemValue("Form", "Memo") 
 13 	 Call email.ReplaceItemValue("SendTo", sendto) 
 14 	 Call email.ReplaceItemValue("Subject", subject) 
 15 	 Call email.ReplaceItemValue("Body", body) 
 16 	 Call email.Send(False)

现在我们在 Java 中为以上示例编码,从为我们提供的 Java 模板代码开始(请参见清单 4)。

清单 4. Java 模板代码
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 
            
            // (Your code goes here) 

        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

在上面清单 3 中 LotusScript 示例的第 1 到 6 行,我们声明了变量 session、database、email、sendto、subject 和 body。因为模板代码已经为我们提供了 session 对象,我们来声明其余的变量(请参见 5)。

清单 5. 声明其余变量
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 

            // (Your code goes here) 

            Database database; 
            Document email; 
            String sendto; 
            String subject; 
            String body; 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

在清单 3 的第 7 到 11 行,我们初始化 database、email、sendto、subject 和 body 变量(请参见清单 6)。如前面所述,必须使用 agentContext 对象而不是 session 对象来获取到当前数据库的句柄。另外,在 Java 中不需要 Set 关键字来设置变量。

清单 6. 初始化变量
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 

            //(Your code goes here) 

            Database database; 
            Document email; 
            String sendto; 
            String subject; 
            String body; 
            database = agentContext.getCurrentDatabase(); 
            email = database.createDocument(); 
            sendto = "Enter _Email _Address _Here"; 
            subject = "Email sent by Java code"; 
            body = "Text in body of email sent by Java code"; 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

在清单 3 的第 12 到 15 行,我们替换了 Form、SendTo、Subject 和 Body 字段的值,并在第 16 行发送了电子邮件。注意调用方法时,Java 不需要 Call 关键字(请参见清单 7)。

另外,尽管 replaceItemValue 和 send 方法在 LotusScript 和 Java 中的拼写一样,您也必须记住在 Java 中要使用正确的大小写(因为 Java 区分大小写)。

清单 7. 设置相应字段并发送电子邮件
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 

            // (Your code goes here) 

            Database database; 
            Document email; 
            String sendto; 
            String subject; 
            String body; 
            database = agentContext.getCurrentDatabase(); 
            email = database.createDocument(); 
            sendto = "Enter _Email _Address _Here"; 
            subject = "Email sent by Java code"; 
            body = "Text in body of email sent by Java code"; 
            email.replaceItemValue("Form", "Memo"); 
            email.replaceItemValue(" SendTo", sendto); 
            email.replaceItemValue(" Subject", subject); 
            email.replaceItemValue("Body", body); 
            email. send(false); 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

LotusScript 中代码到此结束了,但是在 Java 代理中还有一些工作要做。特别是,在 Java 中,我们必须对所有 Domino 对象调用 recycle(请参见清单 8)。调用 recycle 确保分配给这些对象的内存都得以释放。有关 recycle 方法的更多信息,请参见第 4 部分的“recycle() 方法”一段。

清单 8. 对 Domino 对象调用 recycle
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 

            //(Your code goes here) 

            Database database; 
            Document email; 
            String sendto; 
            String subject; 
            String body; 
            database = agentContext.getCurrentDatabase(); 
            email = database.createDocument(); 
            sendto = "Enter_Email_Address_Here"; 
            subject = "Email sent by Java code"; 
            body = "Text in body of email sent by Java code"; 
            email.replaceItemValue("Form", "Memo"); 
            email.replaceItemValue(" SendTo", sendto); 
            email.replaceItemValue(" Subject", subject); 
            email.replaceItemValue("Body", body); 
            email. send(false); 

            //recycle Java Domino objects 
            if (session !=null) 
                session.recycle(); 
            if (agentContext !=null) 
                agentContext.recycle(); 
            if (database !=null) 
                database.recycle(); 
            if (email !=null) 
                email.recycle(); 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

表 6 汇总了两种语言的比较。

表 6. 示例 1 两种语言之间的比较
LotusScriptJava

示例 1:发送电子邮件

 Dim session As New NotesSession 

 Dim database As NotesDatabase 
 Dim email As NotesDocument 
 Dim sendto As String 
 Dim subject As String 
 Dim body As String 

 Set database = session.CurrentDatabase 
 Set email = database.CreateDocument 
 sendto = "Enter_Email_Address_Here"
 subject = "Email sent by LotusScript code"
 body = "Text in body of email sent byLotusScript code"

 Call email.ReplaceItemValue("Form", "Memo") 
 Call email.ReplaceItemValue("SendTo", sendto) 
 Call email.ReplaceItemValue("Subject", subject) 
 Call email.ReplaceItemValue("Body", body) 
 Call email.Send(False)

示例 1:发送电子邮件

 Session session = getSession(); 
 AgentContext agentContext =session.getAgentContext(); 

 Database database; 
 Document email; 
 String sendto; 
 String subject; 
 String body; 

 database = agentContext.getCurrentDatabase(); 
 email = database.createDocument(); 
 sendto = "Enter_Email_Address_Here"; 
 subject = "Email sent by Java code"; 
 body = "Text in body of email sent by Javacode"; 

 email.replaceItemValue("Form", "Memo"); 
 email.replaceItemValue("SendTo", sendto); 
 email.replaceItemValue("Subject", subject); 
 email.replaceItemValue("Body", body); 
 email.send(false); 

 //recycle Java Domino objects 
 if (session !=null) 
    session.recycle(); 
 if (agentContext !=null) 
    agentContext.recycle(); 
 if (database !=null) 
    database.recycle(); 
 if (email !=null) 
    email.recycle();

示例 2:循环通过 Notes 视图

第二个示例中,我们将循环通过 Notes 视图(请参见清单 9)。尽管很简单,该实例在 Java 中编码时却很重要,因为它证实了恰当地使用 recycle 方法可以防止内存异常。

清单 9. 用于循环通过视图的 LotusScript 代码
 1 	 Dim session As New NotesSession 
 2 	 Dim database As NotesDatabase 
 3 	 Dim view As NotesView 
 4 	 Dim document As NotesDocument 
 5 	 Set database = session.CurrentDatabase 
 6 	 Set view = database.GetView("Enter _View _Name _Here") 
 7 	 Set document = view.GetFirstDocument 
 8 	 While (Not document Is Nothing) 
        'Process the document 
 9 	    Print document.Created 
 10 	    Set document = view.GetNextDocument(document) 
 11 	 Wend

以 Java 模板开始,先声明 database、view 和 document 变量(清单 4 中 LotusScript 代码第 1--4 行)。除了这三个变量以外,我们还需要临时的 Document。在 while 循环通过中需要临时 Document 变量来回收当前文档(请参见清单 10)。

清单 10. 声明 database、view 和 document 变量
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 

            //(Your code goes here) 

            Database database; View view; 
            Document document; Document temp; 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

继续到第 5--7 行(请参见清单 9),我们来初始化 database、view 和 document 变量,如清单 11 所示。

清单 11. 初始化 database、view 和 document 变量
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 

            //(Your code goes here) 

            Database database; 
            View view; 
            Document document; 
            Document temp; 
            database = agentContext.getCurrentDatabase(); 
            view = database.getView("Enter_View_Name_Here"); 
            document = view.getFirstDocument(); 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

在清单 9 的 8 — 11 行,我们循环通过视图中的每个文档。对于这个循环,Java 具有相同的 while 关键字;但是必须使用 != 而不是 Not,并且使用 null 来替代 Nothing(请参见清单 12)。

另外,如果我们要在 Java 中为相同的 Domino 变量多次赋值,则需要在赋新值之前对其调用 recycle ,以防止内存泄露(因此需要 temp 变量)。

清单 12. 循环通过视图中的每个文档
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 

            //(Your code goes here) 

            Database database; 
            View view; 
            Document document; 
            Document temp; 
            database = agentContext.getCurrentDatabase(); 
            view = database.getView("Enter_View_Name_Here"); 
            document = view.getFirstDocument(); 
            while (document != null) 	 { 
                //Process the document 
                System.out.println(document.getCreated()); 
                temp = view.getNextDocument(document); // get the next document 
                document.recycle(); // recycle the document we're done with 
                document = temp; 
            } 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

通过对我们创建的所有其他 Domino 对象调用 recycle 包装(wrap up)此示例,如清单 13 所示。

清单 13. 对所有其他 Domino 对象调用 recycle
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 

            // (Your code goes here) 
            
            Database database; 
            View view; 
            Document document; 
            Document temp; 
            database = agentContext.getCurrentDatabase(); 
            view = database.getView("Enter_View_Name_Here"); 
            document = view.getFirstDocument(); 
            while (document != null) 	 { 
                //Process the document 
                System.out.println(document.getCreated()); 
                temp = view.getNextDocument(document); // get the next document 
                document.recycle(); // recycle the document we're done with 
                document = temp; 
            } 
            if (session !=null) 
                session.recycle(); 
            if (agentContext !=null) 
                agentContext.recycle(); 
            if (database !=null) 
                database.recycle(); 
            if (view != null) 
                view.recycle(); 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

表 7 汇总了两种语言的比较。

表 7. 示例 2 两种语言之间的比较
LotusScriptJava

示例 2:循环通过 Notes 视图

 Dim session As New NotesSession 

 Dim database As NotesDatabase 
 Dim view As NotesView 
 Dim document As NotesDocument 

 Set database = session.CurrentDatabase 
 Set view = database.GetView("Enter_View_Name_Here") 
 Set document = view.GetFirstDocument 

 While (Not document Is Nothing) 
    'Process the document 
    Print document.Created 
    Set document = view.GetNextDocument(document) 
 Wend

示例 2:循环通过 Notes 视图

 Session session = getSession(); 
 AgentContext agentContext = session.getAgentContext(); 

 Database database; 
 View view; 
 Document document; 
 Document temp; 

 database = agentContext.getCurrentDatabase(); 
 view = database.getView("Enter_View_Name_Here"); 
 document = view.getFirstDocument(); 

 while (document != null){ 
    //Process the document 
    System.out.println(document.getCreated()); 
    
    // get the next document 
    temp = view.getNextDocument(document); 
    
    // recycle the documentwe're done with 
    document.recycle(); 
    document = temp; 
 } 

 if (session !=null) 
    session.recycle(); 
 if (agentContext !=null) 
    agentContext.recycle(); 
 if (database !=null) 
    database.recycle(); 
 if (view != null) 
    view.recycle();

示例 3:用邮件数据库信息生成报告

最后一个示例使用广泛。这里我们循环通过 Domino 服务器上的邮件数据库并用来自每个邮件文件的各个项创建一个电子邮件报告。首先,花些时间看一下清单 14 中的 LotusScript 示例。

清单 14. LotusScript 代码示例
 1 	 Dim session As New Notessession 
 2 	 Dim nab As New Notesdatabase("Enter_Server_Name_Here", "names.nsf") 
 3 	 Dim reportDatabase As Notesdatabase 
 4 	 Dim personDocument As NotesDocument 
 5 	 Dim report As NotesDocument 
 6 	 Dim view As NotesView 
 7 	 Dim temp As String 

 8 	 Set reportDatabase = session.CurrentDatabase 
 9 	 Set report = reportDatabase.CreateDocument 

 10 	 Call report.ReplaceItemValue("Form" , "Memo") 
 11 	 Call report.ReplaceItemValue("Subject" , "Mail Applications Report") 

 12 	 Dim richTextItem As New NotesRichTextItem(report, "Body") 
 13 	 Set view = nab.GetView("People") 
 14 	 Set personDocument = view.GetFirstDocument 
 15 	 While Not personDocument Is Nothing 
 16 	    On Error Resume Next 
 17 	    Dim mailDatabase As New NotesDatabase(personDocument.mailserver(0), 
            personDocument.mailfile(0)) 
 18 	    If mailDatabase.IsOpen Then 
 19 	        temp = "Mail Owner: " & personDocument.fullname(0) & " Size: " & 
            Cstr(mailDatabase.size) & " _ bytes Template: " 
            + mailDatabase.DesignTemplateName 
 20 	    Else 
 21 	        temp = "Could not open mail file for: " & personDocument.fullname(0) & 
            " Server: " & personDocument.mailserver(0) & " , " 
            & personDocument.mailfile(0) 
 22 	    End If 

 23 	    richTextItem.AppendText(temp) 
 24 	    richTextItem.AddNewline( 1) 
 25 	    temp = ""
 26 	    Set personDocument = view.GetNextDocument(personDocument) 
 27  Wend 

 28 	 Call report. Send(False, "Enter_Email_Address_Here")

我们从第 1--7 行开始(在清单 14 中),声明需要的变量,然后初始化 nab Database 变量。在 Java 中,注意必须使用 session 对象来设置 nab(请参见清单 15)。

清单 15. 声明变量
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 

            // (Your code goes here) 
    
            Database nab; 
            nab = session.getDatabase("Enter_Server_Name_Here","names.nsf"); 
            Database reportDatabase; 
            Document personDocument; 
            Document report; 
            Document tempDocument; 
            View view; 
            String temp; 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

LotusScript 第 8--14 行(清单 14 中)与 Java 等价代码之间最大的不同之处是 RichTextItem 类;在 Java 中,需要使用 Document 类的 createRichTextItem 方法来创建富文本字段(请参见清单 16)。

清单 16. 初始化变量并创建报告电子邮件
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 

            // (Your code goes here) 

            Database nab; 
            nab = session.getDatabase("Enter_Server_Name_Here","names.nsf"); 
            Database reportDatabase; 
            Document personDocument; 
            Document report; 
            Document tempDocument; 
            View view; 
            String temp; 
            reportDatabase = agentContext.getCurrentDatabase(); 
            report = reportDatabase.createDocument(); 
            report.replaceItemValue("Form" , "Memo"); 
            report.replaceItemValue("Subject" , "Mail Applications Report"); 
            RichTextItem richTextItem; 
            richTextItem = report.createRichTextItem("Body"); 
            view = nab.getView("People"); 
            personDocument = view.getFirstDocument(); 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

在清单 14 的第 15--27 行,我们在 while 循环中完成了大量工作。在 Java 中,我们使用 try/catch 块进行错误处理,而不像在 LotusScript 中那样使用 On Error 语句。因为 getDatabase 方法可能抛出异常,我们利用 catch 块来设置 temp 字符串变量(请参见清单 17)。

在 Java 中要记住的另一件事是重用 Domino 变量时要在循环内使用 recycle 方法。在这个特殊的 while 循环中,我们必须记住在每次新的赋值之前回收 mailDatabase 和 personDocument。

清单 17. 收集邮件数据库信息
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 
            
            // (Your code goes here) 

            Database nab; 
            nab = session.getDatabase("Enter_Server_Name_Here","names.nsf"); 
            Database reportDatabase; 
            Document personDocument; 
            Document report; 
            Document tempDocument; 
            View view; 
            String temp; 
            reportDatabase = agentContext.getCurrentDatabase(); 
            report = reportDatabase.createDocument(); 
            report.replaceItemValue("Form" , "Memo"); 
            report.replaceItemValue("Subject" , "Mail Applications Report"); 
            RichTextItem richTextItem; 
            richTextItem = report.createRichTextItem("Body"); 
            view = nab.getView("People"); 
            personDocument = view.getFirstDocument(); 
            while (personDocument != null) 
            { 
                Database mailDatabase; 
                try { 
                    mailDatabase = session.getDatabase ( 
                        personDocument.getItemValueString("MailServer"), 
                        personDocument.getItemValue String ("MailFile")); 
                    temp = "Mail Owner: " + personDocument.getItemValueString("FullName") 
                        + " Size: " + mailDatabase.getSize() 
                        + " _ bytes Template: " + mailDatabase.getDesignTemplateName(); 
                    mailDatabase.recycle(); 
                } catch (Exception e) { 
                    temp = "Could not open mail file for: " + 
                        personDocument.getItemValueString("FullName") + " Server: " + 
                        personDocument.getItemValueString("MailServer") + " , " + 
                        personDocument.getItemValueString("MailFile"); 
                } 
                richTextItem.appendText(temp); 
                richTextItem.addNewLine(1); 
                temp = ""; 
                tempDocument = view.getNextDocument(personDocument); 
                personDocument.recycle(); 
                personDocument = tempDocument; 
            } 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

通过发送电子邮件(清单 14 的第 28 行),然后回收我们创建的其余 Domino 对象(请参见清单 18)包装此示例。

清单 18. 发送电子邮件并回收 Domino 对象
 import lotus.domino. *; 
 public class JavaAgent extends AgentBase { 
    public void NotesMain() { 
        try { 
            Session session = getSession(); 
            AgentContext agentContext = session.getAgentContext(); 

            // (Your code goes here) 
            
            Database nab; 
            nab = session.getDatabase("Enter_Server_Name_Here","names.nsf"); 
            Database reportDatabase; 
            Document personDocument; 
            Document report; 
            Document tempDocument; 
            View view; 
            String temp; 
            reportDatabase = agentContext.getCurrentDatabase(); 
            report = reportDatabase.createDocument(); 
            report.replaceItemValue("Form" , "Memo"); 
            report.replaceItemValue("Subject" , "Mail Applications Report"); 
            RichTextItem richTextItem; 
            richTextItem = report.createRichTextItem("Body"); 
            view = nab.getView("People"); 
            personDocument = view.getFirstDocument(); 
            while (personDocument != null) 
            { 
                Database mailDatabase; 
                try { 
                    mailDatabase = session.getDatabase ( 
                        personDocument.getItemValueString("MailServer"), 
                        personDocument.getItemValue String ("MailFile")); 
                    temp = "Mail Owner: " + personDocument.getItemValueString("FullName") 
                        + " Size: " + mailDatabase.getSize() 
                        + " _ bytes Template: " + mailDatabase.getDesignTemplateName(); 
                    mailDatabase.recycle(); 
                } catch (Exception e) { 
                    temp = "Could not open mail file for: " + 
                        personDocument.getItemValueString("FullName") + " Server: " + 
                        personDocument.getItemValueString("MailServer") + " , " + 
                        personDocument.getItemValueString("MailFile"); 
                } 
                richTextItem.appendText(temp); 
                richTextItem.addNewLine(1); 
                temp = ""; 
                tempDocument = view.getNextDocument(personDocument); 
                personDocument.recycle(); 
                personDocument = tempDocument; 
            } 
            report.send(false, "Enter_Email_Address_Here"); 
            if (session !=null) 
                session.recycle(); 
            if (agentContext !=null) 
                agentContext.recycle(); 
            if (nab != null) 
                nab.recycle(); 
            if (reportDatabase !=null) 
                reportDatabase.recycle(); 
            if (personDocument !=null) 
                personDocument.recycle(); 
            if (report !=null) 
                report.recycle(); 
            if (view !=null) 
                view.recycle(); 
            if (richTextItem !=null) 
                richTextItem.recycle(); 
        } catch(Exception e) { 
            e.printStackTrace(); 
        } 
    } 
 }

表 8 汇总了两种语言的比较。

表 8. 示例 3 两种语言之间的比较
LotusScriptJava

示例 3:用邮件数据库信息生成报告

 Dim session As New Notessession 

 Dim nab As New Notesdatabase( 
   "Enter_Server_Name_Here", 
   "names.nsf") 

 Dim reportDatabase As Notesdatabase 

 Dim personDocument As NotesDocument 
 Dim report As NotesDocument 

 Dim view As NotesView 
 Dim temp As String 

 Set reportDatabase = session.CurrentDatabase 
 Set report = reportDatabase.CreateDocument 

 Call report.ReplaceItemValue("Form" , "Memo") 
 Call report.ReplaceItemValue("Subject" , 
   "MailApplications Report") 

 Dim richTextItem As New NotesRichTextItem(report, 
   "Body") 

 Set view = nab.GetView("People") 
 Set personDocument = view.GetFirstDocument 
 While Not personDocument Is Nothing 
   On Error Resume Next 
   Dim mailDatabase As New NotesDatabase( 
      personDocument.mailserver(0), 
      personDocument.mailfile(0)) 
   If mailDatabase.IsOpen Then 
      temp = "Mail Owner: " & 
         personDocument.fullname(0) & 
         "Size: " & Cstr(mailDatabase.size) & 
         " _ bytes Template: " + 
         mailDatabase.DesignTemplateName 
   Else 
      temp = "Could not open mail file for: " & 
         personDocument.fullname(0) & 
         "Server: " & 
         personDocument.mailserver(0) & 
         " , " & personDocument.mailfile(0) 
   End If 
   
   richTextItem.AppendText(temp) 
   richTextItem.AddNewline(1) 
   temp = ""
   Set personDocument=view.GetNextDocument( 
      personDocument) 
 Wend 
 Call report.Send(False,"Enter_Email_Address_Here")

示例 3:用邮件数据库信息生成报告

 Session session = getSession(); 
 AgentContext agentContext =session.getAgentContext(); 

 Database nab; 
 nab = session.getDatabase("Enter_Server_Name_Here", 
   "names.nsf"); 
 Database reportDatabase; 

 Document personDocument; 
 Document report; 
 Document tempDocument; 
 View view; 
 String temp; 

 reportDatabase =agentContext.getCurrentDatabase(); 
 report = reportDatabase.createDocument(); 

 report.replaceItemValue("Form" , "Memo"); 
 report.replaceItemValue("Subject" , 
   "MailApplications Report"); 

 RichTextItem richTextItem; 
 richTextItem = report.createRichTextItem("Body"); 

 view = nab.getView("People"); 
 personDocument = view.getFirstDocument(); 
 while (personDocument != null) 
 { 
   Database mailDatabase; 
   try { 
      mailDatabase = session.getDatabase( 
      personDocument.getItemValueString("MailServer"), 
      personDocument.getItemValueString("MailFile")); 
      
      temp = "Mail Owner: " + 
         personDocument.getItemValueString("FullName") + 
         "Size: " + mailDatabase.getSize() + 
         " _bytes Template: " + 
         mailDatabase.getDesignTemplateName(); 
      mailDatabase.recycle(); 
   } catch (Exception e) { 
      temp = "Could not open mail file for: " + 
         personDocument.getItemValueString("FullName") + "
         Server: " + 
         personDocument.getItemValueString("MailServer") + 
         " , " + 
         personDocument.getItemValueString("MailFile"); 
   } 

   richTextItem.appendText(temp); 
   richTextItem.addNewLine(1); 
   temp = ""; 
   tempDocument = view.getNextDocument(personDocument); 
   personDocument.recycle(); 
   personDocument = tempDocument; 
 } 
 report.send(false,"Enter_Email_Address_Here"); 

 if (session !=null) 
   session.recycle(); 
 if (agentContext !=null) 
   agentContext.recycle(); 
 if (nab != null) 
   nab.recycle(); 
 if (reportDatabase !=null) 
   reportDatabase.recycle(); 
 if (personDocument !=null) 
   personDocument.recycle(); 
 if (report !=null) 
   report.recycle(); 
 if (view !=null) 
   view.recycle(); 
 if (richTextItem !=null) 
   richTextItem.recycle();

其他要素

我们进一步介绍一些与我们讨论的 Java 代码和 LotusScript 相关的其他要素。

JVM版本。与 LotusScript 不同,Java 代码运行在 Java 虚拟机 (JVM) 上。表 9 显示了与各个 Notes/Domino 版本一起提供的 JVM 版本。

表 9. JVM 和 Notes/Domino 版本

Notes/Domino版本JVM版本
6.5.x1.3.1
7.0.x1.4.2
8.0.x1.5.0
8.51.6.0

JVM 在普通客户机 / 服务器安装期间安装并且与安装在操作系统上的 JVM 无关。使用 JVM 提供的类时版本很重要,因为不同版本之间有一些不同之处。

recycle() 方法。如果在 Designer 帮助文件中浏览 Domino 类,会注意到每个 Java 类都有一个额外的方法,名为 recycle 方法(LotusScript 中没有相应方法)。此方法说明(选自帮助文件)解释道 “recycle 方法无条件地销毁对象并将其内存归还给系统”。

我们不打算深入解释为什么应该调用 recycle 方法,因为此主题在 Lotus Support Technote #1097861, “Why it is important to use Recycle() method on every Java object” 中进行了详细介绍。只要记住,要防止内存泄露,应该总是对创建的所有 Domino Java 对象调用 recycle 方法。

安全异常。因为 Java 代码运行在 JVM 上,Java 代码有一个额外的安全层,在使用 LotusScript 时没有提供。取决于使用的 Java 类 / 方法,在 Lotus Domino 中运行 Java 代码时可能会遇到安全异常,比如 java.security.AccessControlException 异常。

如果确实遇到了安全异常,必须在 JVM 的 java.policy 文件中明确授予访问权限。有关更多信息,请参见 Lotus Support Technote #1279509, “Security exceptions are encountered when developing Java agents”。

将外部 JAR 文件与 Java 代理一起使用。类似于 LotusScript .lss 文件,Java 代理可以使用现有 Java 类。如果 JAR 文件带有要使用的 Java 类,可以通过使用以下三种方法之一,使这些类对于代理可用:

  • 将 JAR 文件附加到代理本身:
  1. 在 Domino Designer 中打开 Java 代理并单击 “Edit Project”。
  2. 在 Base 目录字段选择 JAR 文件所在的目录。
  3. 选择并添加 JAR 文件。
  • 将 JAR 文件复制到 {Lotus Notes\Domino program directory}\jvm\lib\ext。
  • 使用 JavaUserClasses Notes.ini 变量;在 Notes 或 Domino Notes.ini 文件中,添加该变量并指向一个或多个 JAR 文件,例如:

JavaUserClasses=C :\jar_files\file1 .jar;C:\jar_files\file2.jar

注:使 JAR 文件可用后,必须在代理中使用 import语句引用要使用的特定类。


结束语

希望本文能帮助传统 Domino 开发人员轻松开始其在 Domino Designer 中开发 Java 代理之旅。上述示例可以作为模板代码,用于开发更广泛的 Java 代理。记住 Domino Designer 8.5 帮助文件为每个 Domino 类提供了大量 Java 示例。

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Lotus, Java technology
ArticleID=435648
ArticleTitle=在 IBM Lotus Domino Designer 中使用 Java 构建应用程序
publish-date=10142009