借助 Project Zero 在 Web 2.0 领域创建 RESTful IBM Lotus Domino 应用程序

用 Project Zero 为 Lotus Domino 提供 REST 支持

大多数 Lotus Domino 开发人员都熟悉采用各种语言(LotusScript. 最为著名)编写的 Lotus Domino 代理。基本上,RESTful 应用程序(具有之前介绍的 REST 原则)都可通过 Web 访问。此外,可以通过命名资源对应用程序寻址。使用 LotusScript. 或简单代理等约定来实例化应用程序脱离了 REST 的基础,即命名资源。

Lotus Domino 代理需使用类似于 http://domino.ibm.com/database.nsf/AgentName?OpenAgent 的 URL 通过 Web 调用,如图 1 所示。这绝非我们希望实现的命名资源,并且任何信息都可作为参数传递。这种实现或等价的 servlet 实现与基于动词的实现同义,而不同与 RESTful 特性。举例来说,代理或 servlet 可以接受 ?action=create&user=vstaub 这样的参数;而另一方面,RESTful 方式只操作 POST 方法中的数据。


图 1. Lotus Domino 代理的命名资源
Lotus Domino 代理的命名资源

Lotus Domino Security API (DSAPI) 过滤器可能是一个比较合适的实现。DSAPI 过滤器位于 Lotus Domino HTTP 栈,并且可以在满足 URL 中的条件时调用。熟悉 IBM Lotus Quickr 人的都知道,所有 URL containing /quickr 都由 Lotus Quickr 服务器的 DSAPI 过滤器处理。使用 DSAPI 过滤器,实现将有效地嵌入到 Lotus Domino 服务器的 HTTP 栈中。遗憾的是,创建 DSAPI 对许多人来说都是一项令人畏惧的任务,因为它要求同时掌握 DSAPI 工具包和 C 编程语言。如果 RESTful 应用程序旨在促进 /database/document_unid 或 /database/view_name 命名资源约定,那么它可以与已有 Lotus Domino Web 服务器无缝操作,从而在预先定义的条件下调用 RESTful 操作。请参见图 2。根据读者的背景,此实现可能过于技术化或费时。


图 2. Lotus Domino DSAPI 过滤器的命名资源
Lotus Domino DSAPI 过滤器的命名资源

最后,考虑 Java 语言。自 Lotus Domino 6 以来,我们能够使用 Java 访问 Lotus Domino 资源,如数据库、视图或支持 Java 的应用程序中的文档。在 Java 访问中结合 servlet 便利 Web 请求,并且您可通过解决方案在互联网上与 Lotus Domino 资源交互。但如前所述,servlet 实现并非完全是 RESTful 的。通过使用日益流行的 Project Zero 项目,应用程序的支持 Web 的 RESTful 功能得到了极大的改进。


图 3. Project Zero 应用程序的命名资源
Project Zero 应用程序的命名资源 

识别资源

在 Lotus Domino Directory 中,我们可以识别以下资源:

  • Employee:个人记录(等价于 Lotus Notes 文档)。
  • Employees:一组员工(等价于一个 Lotus Notes 文档或一个 Lotus Notes 视图)。

识别资源的另一个重要方面是理解它的寻址方式。作为默认端点的的一部分,员工是可访问的:http://[hostname]/employees。

可以使用简短名称或电子邮件等惟一标识符来访问员工:http://[hostname]/employees/[uid]。

资源表示

Lotus Domino Employees 应用程序和客户机或浏览器之间的数据交换是使用 JavaScript. Object Notation (JSON) 完成的。使用 JSON 的原因在于已有的 Project Zero 支持以及它在 JavaScript. 应用程序中提供的轻量级且易于使用的数据格式。基本上,JSON 用于表示数据,并且 Lotus Domino Directory 中的用户可以作为 JSON 对象出现,如清单 1 所示。


清单 1. 员工的 JSON 表示

{
      "FirstName": "Van",
      "FullName": "CN=Van Staub\/O=IBM",
      "HTTPPassword": "(355E98E7C7B59BD810ED845AD0FD2FC4)",
      "InternetAddress": "vstaub_cnnew1@ibm.com",
      "LastName": "Staub",
      "OfficeCity": "Atlanta",
      "OfficePhoneNumber": "(123) 456-7890",
      "OfficeState": "Ga",
      "OfficeStreetAddress": "4111 Northside Pkwy",
      "ShortName": "vstaub"
}

本文将在稍后介绍,在 JavaScript. 客户机中使用该数据的能力是即时的。JavaScript. 客户机应用程序将 JSON 作为对象接收,因此需使用点表示(dot notation)语法引用它的值。举例来说,要访问用户的姓,需要使用语法 object.LastName。此语法将降低任何解析需求,并便利对数据的直接访问。有关 JSON 的更多信息,请参阅 JSON 网站

映射方法

表 1 演示了用于实现各用例的 HTTP 方法。


表 1. 用例 HTTP 方法类型

用例资源HTTP 方法
查看员工员工GET
查看员工员工GET
创建员工员工POST
更新员工员工PUT
删除员工员工DELETE

响应代码

表 2 详细给出了操作的 HTTP 响应以及错误情况下的服务响应。针对 GET、POST、PUT 和 DELETE 的任何成功请求都将获得一个 200 OK 响应,但错误条件将触发相应的 HTTP 响应。


表 2. 用例 HTTP 代码

用例 失败
查看员工401(未授权)
404(无法找到员工)
查看员工401(未授权)
404(无法找到 UID)
创建员工401(未授权)
303(指定 UID 已存在)
更新员工401(未授权)
403(禁止)
删除员工401(未授权)
403(禁止)

使用 Project Zero 设计

Project Zero 允许开发人员快速创建支持 Web 的应用程序,从而可以专注于 REST。简言之,只需结合少许 Java 编程和 Project Zero,您便可创建和部署 RESTful Lotus Domino 应用程序或服务。Lotus Domino Employees 应用程序使用已有的 Project Zero Employees 演示应用程序解决许多客户端逻辑。这允许读者实现 Project Zero 的多功能性,并且能结合新的特定于 Lotus Domino 的服务端逻辑。

Project Zero 让您能够专注于应用程序的业务逻辑,而不用为处理传入 Web 请求、解析 URL 和处理各种方法大费周折。可以通过两种方法实现 Project Zero 应用程序:PHP 和 Groovy。Groovy 实现巧妙地补充了使用 Java 访问 Lotus Domino 资源的功能。从本质上说,通过在 Groovy 代码中使用 Java,或调用已有 Java 库中的函数,我们可以编写直接访问 Lotus Domino 资源的 Groovy 应用程序。选择在 Groovy 实现,我们可以利用一款 Eclipse 插件来加速应用程序的创建和测试。再说一次,这允许您轻松地完成创建、部署和测试流程。

RESTful Lotus Domino 应用程序和大多数 Project Zero 应用程序的核心都是 RESTful 设计。Project Zero 允许您创建 Groovy 文件(它是一个处理程序)来提供命名资源。然后,客户机可以传递一个虚拟命名资源给处理程序。举例来说,您创建了一个名称为 employees.groovy 的处理程序脚本。然后,用户可通过 URL 访问命名资源 /employees。然后,针对 /employees 的请求可以将目录的整个内容提供给客户机。/employees/username 就是一个类似的 URL 请求。用户名成员是一个虚拟资源。employees.groovy 允许对用户名的值进行访问,而实现又恰当给出了句柄的详细信息。请注意虚拟命名资源和 Groovy 处理程序的文件名称之间的关系。处理程序的实现细节模拟了 REST 架???。创建、更新、检索和删除(CRUD)等操作通过 Groovy 处理程序中的相应函数得以简化,如表 3 所示。


表 3. 定义 Groovy 处理程序

方法类型URLGroovy 处理程序函数
GET /employeesonList()
POST /employeesonCreate()
GET /employees/[uid]onRetrieve()
PUT /employees/[uid]onUpdate()
DELETE /employees/[uid]onDelete()

虽然我们所讨论的多数信息都专注于服务器端,但 Project Zero 也简化了客户端应用程序的创建。流行的 Ajax 框架 Dojo 封装在一个增件库中。因此,您可以创建传入服务请求和支持 Ajax 的富 Web 应用程序。

如果决定使用 Project Zero,那么您将体验激动人心的一流的开发应用程序和架构,并能将 Eclipse 中的一切内容整合到更加开放的 Web 2.0 中。

此外,Project Zero 支持将对象隐式转换为 JavaScript. 表示,即 JSON。我们可以将 Java 对象作为响应轻易提供给客户机,然后该对象将自动转换为 JSON 表示。我们可以轻易利用 Project Zero 平台的便利功能。

Lotus Domino Employees 应用程序由分层的实现策略组成:一个客户机应用程序、Project Zero 应用程序、一组 Java 类和 Lotus Domino 服务器本身,如图 4 所示。


图 4. Lotus Domino 员工应用程序模型
Lotus Domino 员工应用程序模型

客户机(支持 Web 的 JavaScript. 应用程序或自定义服务)将连接到 Project Zero 应用程序。Project Zero 负责与客户机的任何交互,其任务涉及处理传入请求、查找命名资源和发送适当响应。Project Zero 消除了处理传入 Web 请求所需的开销。通过使用内置的 Project Zero 函数来处理 CRUD 操作,我们不必与往常一样在 Web 服务器应用程序中编写大量代码。

Java 类负责与 Lotus Domino 服务器交互。从本质上说,Java 类就是 Lotus Domino Employees 应用程序的逻辑,其实就是一组帮助函数。这些帮助函数可以利用 Lotus Domino Java API 和 notes.jar 文件与存储在 Lotus Domino Directory 中的数据进行交互。

您可以毫不费力地编写代码让 Groovy 类与 Lotus Domino 交互,但我们推荐将应用程序逻辑作为帮助函数分离到 Java 类中。由于 Java 类与 Project Zero 是松散耦合的,因此可以在其他场景中重用应用程序 —— 比如说富客户机或 servlet 中。同样,使用 Java 编写的访问 Lotus Domino 服务器的应用程序可以轻易地整合到 Project Zero 平台中,从而提供支持 Web 的交付。

应用程序行为

我们使用之前介绍的策略来考虑任何 Lotus Domino 应用程序的操作流。假设某客户机操作向 Project Zero 应用程序发起一个异步调用。Project Zero 仅能接收请求和调用必要的 Java 代码来促进所需的操作。Java 类与 Lotus Domino 服务器上的数据交互。然后,可以将 Java 对象序列化并发回请求者。

Lotus Domino Employees 应用程序由一些非常简单的交互构成,即根据对用户的传入操作与 Lotus Domino 进行交互:

  1. 检索 Person 文档中的信息。
  2. 删除 Person 文档。
  3. 注册新用户。
  4. 更新 Person 文档。

表 4 详细说明了 Lotus Domino 服务器的行为。


表 4. 定义 Lotus Domino 行为

方法类型URLGroovy 处理程序函数Lotus Domino 行为
GET/employeesonList()检索 Person 文档中的信息
POST /employeesonCreate() 注册新用户
GET /employees /[uid]onRetrieve()检索 Person 文档中的信息
PUT/employees/[uid]onUpdate()更新 Person 文档
DELETE /employees/[uid]onDelete() 删除 Person 文档

利用 Lotus Domino 安全性

为解决安全问题,我们将使用已有的 Domino 机制:多服务器单点登录(SSO)。Web 用户成功通过 Lotus Domino 的身份验证之后,Lotus Domino 服务器将以 cookie 的形式发起一个加密令牌给浏览器。cookie 中的值可用于身份验证目的。在这种方式下,我们重复使用 cookie 中的加密令牌连接 Project Zero 应用程序中的 Lotus Domino。这对于保护到 Project Zero Web 应用程序的访问具有双重效果:

  • 它确保只有有效用户才可以使用应用程序(身份验证)。
  • 它确保用户访问 Lotus Domino 时只可获得自己权限范围内的内容(授权)。

Project Zero 最近提供了对新的 Lotus Domino LTPAToken 的支持。通过结合 cookie 中的 LTPAToken 值,我们可以根据用户的身份来创建 Lotus Notes 会话。与 Lotus Domino 的所有交互都将从 Lotus Notes 会话的创建开始。

要利用 LTPAToken,管理员可以将服务器配置为单点登录。可以在 IBM Lotus Domino Administrator 或 Lotus Notes 客户机中完成此操作,方法是??建一个 Web SSO Configuration 文档,如图 5 所示。


图 5. 创建 Lotus Domino Web SSO Configuration 文档
创建 Lotus Domino Web SSO Configuration 文档

接下来,配置 Lotus Domino 服务器在 Server 文档中使用 Web SSO Configuration 文档,方法是使用刚才创建的 Web SSO 配置将 Session 身份验证方法更新为 Mutliple Servers (SSO)。参见图 6。


图 6. 为 Lotus Domino 配置 SSO
为 Lotus Domino 配置 SSO

注意,Lotus Domino 生成的 LTPAToken 仅对于 Web SSO Configuration 文档中列出的 DNS 域有效。此外,LTPAToken 只传递给使用 Web SSO Configuration 文档中的域访问的服务器。从本质上说,这表示您希望使用与访问 Lotus Domino 相同的 URL 来访问 Lotus Domino Employees Web 应用程序。不要使用本地主机名或 IP 地址。

要获取 LTPAToken,登录到 Lotus Domino 服务器,如图 7 所示。


图 7. 在浏览器中创建 LTPAToken
在浏览器中创建 LTPAToken

在浏览器的地址栏输入以下消息,验证您的 LTPAToken:

javascript.:alert(document.cookie)

请参见图 8。


图 8. 确认您拥有 LTPAToken
确认您拥有 LTPAToken

使用 Lotus Notes 会话对象

使用 Java 类与 Lotus Domino 的所有交互都源自会话对象。通过会话对象,程序员可以发起各种强大的操作,如打开数据库、发送控制台命令、检索 Notes.ini 名称/值对和注册新用户。在 Lotus Domino Employees 应用程序中,会话对象使用从浏览器传递到应用程序的 LTPAToken 构建。这种流程允许应用程序只执行登录用户权限范围内的操作。

获取 Lotus Notes 会话对象的详细信息也是值得一提的。根据开发环境以及所实现应用程序的目的,对象的实现形式也有所不同。Lotus Domino 设计者编程指南,第 3 卷 Java CORBA 类 概述了获取 Lotus Notes 会话对象之间的差异。

可以使用以下两种方式创建 Lotus Notes 会话对象:使用远程过程调用(Remote Procedure Call,RPC)或使用 Internet 对象请求代理间协议(Internet Inter-ORB Protocol,IIOP)。RPC 调用要求将 Lotus Notes 客户机、IBM Lotus Domino Designer 或 Lotus Domino 服务器安装在运行的应用程序的本地。Lotus Domino Employees 应用程序就是这种形式的一个例子,它将在运行中的 Lotus Domino 服务器上创建一个本地会话。这种选择旨在最大限度地提升性能,以提供快速响应的 Web 接口。

为 Project Zero 配置 RPC 会话

要执行任何 Lotus Notes Java 编程,必须在项目的类路径中包含合适的 Lotus Notes Java 库。在使用 RPC 调用时,需在应用程序的 Java 编译路径中包括 notes.jar 文件。第一次运行 Project Zero 应用程序时,可能会出现如图 9 所示的错误消息。


图 9. 缺少 Lotus Notes Java 库
缺少 Lotus Notes Java 库

从本质上说,此错误表示无法找到 nlsxbe 库的本机调用,您必须将它添加到 Project Zero 应用程序的 java.library.path 变量中。notes.jar 库向 Lotus Domino 程序目录中的函数发起本机调用。反过来,本机函数又调用其他本机函数。如果您在 Eclipse 中有过 Lotus Notes Java 编程经验,那么可能知道最简单的解决方案就是将 Lotus Domino 或 Lotus Notes 程序目录添加到系统的 PATH 环境变量中。在 Project Zero 中,需求则稍有不同。要解决之前的错误,将 Lotus Domino 或 Lotus Notes 程序目录的路径添加到 Project Zero 应用程序的运行时配置中,如图 10 和 11 所示。

在 Run 对话框中选择 Arguments 选项卡,如图 10 所示。然后,在 VM 参数窗格中,将 Lotus Domino 或 Lotus Notes 安装的路径附加到 java.library.path 参数中:

-Djava.library.path="${ZERO.NATIVES};C:/Lotus/Domino"

记住使用分号将任何已有参数与最新添加的 Lotus Domino 或 Lotus Notes 安装路径分隔开。


图 10. 配置 Lotus Domino VM 参数
配置 Lotus Domino VM 参数

在 Run 对话框中选择 Environment 选项卡,如图 11 所示。编辑列表中的 PATH 变量,然后在出现的 Edit Environment Variable 对话框中附加 Lotus Domino 或 Lotus Notes 安装的路径。

再说一次,记住使用分号将任何已有参数与最新添加的 Lotus Domino 或 Lotus Notes 安装路径分隔开。


图 11. 配置 Lotus Domino PATH 变量值
配置 Lotus Domino PATH 变量值

创建 RPC 会话

假设用户已经通过了 Lotus Domino 服务器的身份验证,Groovy 文件会将 LTPAToken 传递给 Java SessionHelper 类。

Session session= SessionHelper.getInstance()
.getSession(zget("/request/cookies/in").get("LtpaToken"));

而 SessionHelper 类将创建 Lotus Notes 会话对象,如清单 2 所示。


清单 2. Lotus Notes 会话对象的创建

// verify that the Zero HTTP thread has been properly
// initialized for Notes RPC communication
Long threadId= new Long(NotesThread.currentThread().getId());
		
System.out.println("Zero thread : " + threadId + " using LtpaToken : " + ltpaToken);
		
…
// already created the NotesThread?
if(sessions.containsKey(threadId)){
	// not really an error
	System.err.println("NotesThread already initialized");
} else {
	System.out.println("Initializing NotesThread");
		
	// initialize the NotesThread
	NotesThread.sinitThread();
}
			
// create a Notes Session
// use null to indicate an RPC connection to the
// server on which the Project Zero application runs
Session session= NotesFactory.createSession(null, ltpaToken);
		
System.out.println("Storing NotesSession for Zero thread : " + threadId);
		
// cache the session for future use
sessions.put(threadId, session);
		
System.out.println("NotesSession created for user " + session.getUserName());
		
return session;

…

在发起 RPC 调用时,必须在初始化 NotesThread 对象之后才能利用该会话。此步骤并非 IIOP 实现所必需的。您还必须在处理结束时调用 stermThread 函数,以避免异常终结对运行中的 Lotus Domino 服务器造成影响。获得会话对象之后,可以使用由 LTPAToken 定义的授权给用户的访问控制级别在它与 Lotus Domino 服务器之间实现交互。

大多数时间,我们所投资的??目都涉及到如何处理 Lotus NotesThread 对象。Project Zero 应用程序默认使用三个单独的线程以轮叫的形式处理传入 HTTP 请求。在与 Lotus Domino 交互之前,NotesThread 类必须正确完成各个请求的初始化任务。初始化失败通常将导致清单 3 所示的错误。


清单 3. 未正确初始化 NotesThread 的错误

Caused by: java.lang.UnsatisfiedLinkError: NCreateSessionWithTokenOrName
	at lotus.domino.local.Session.NCreateSessionWithTokenOrName(Native Method)
	at lotus.domino.local.Session.createSessionWithTokenOrName(Unknown Source)
	at lotus.domino.NotesFactory.createSessionC(Unknown Source)
	at lotus.domino.NotesFactory.createSession(Unknown Source)
	at com.ibm.devworks.SessionHelper.createSession(SessionHelper.java:24)
	at com.ibm.devworks.SessionHelper.getSession(SessionHelper.java:60)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod.invoke
	(ReflectionMetaMethod.java:56)
	at org.codehaus.groovy.runtime.MetaClassHelper.doMethodInvoke
	(MetaClassHelper.java:599)
	at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1030)
	at org.codehaus.groovy.runtime.Invoker.invokeMethod(Invoker.java:69)
	at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:66)
	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN
	(ScriptBytecodeAdapter.java:165)
	at employees.onList(employees.groovy:23)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod.invoke
	(ReflectionMetaMethod

UnsatisfiedLinkError 表示 NotesThread 未正确初始化。

完成初始化之后,HTTP 线程必须得到正确处理。NotesThread.stermThread() 函数为线程的处理任务提供了方便。我们的意图是在 Zero 中接收到传入请求时初始化 Zero HTTP 线程,随后处理 NotesThread 并呈现输出。请参见清单 4。


清单 4. 处理会话对象和 NotesThread

def onList() {

    try {
        
        // create a Session from the SessionHelper
        // all Domino operations require a Session
        Session session= SessionHelper.getInstance()
        .getSession(zget("/request/cookies/in").get("LtpaToken"));
        
        …

    } catch (NotesException e) {

        request.status = HttpURLConnection.HTTP_INTERNAL_ERROR
          request.error.message = e.getMessage()
        request.view = "error"

    }
    
    // properly dispose of any Domino objects by using the
    // SessionHelper
    SessionHelper.getInstance().shutdown();
    
    // finally render the content to the client
    render()

}

/**
* Properly dispose of any remaining Sessions or NotesThreads.
*
*/
public void shutdown() {
    
    System.out.println("Closing NotesSession ...");
    
    // get the Zero thread requesting Notes shutdown
    Long threadId= new Long(NotesThread.currentThread().getId());
    
    try {
        Session session= (Session)sessions.get(threadId);
    
        System.out.println("Closing NotesSession for user " + session.getUserName());
        
        session.recycle();
        
        System.out.println("NotesSession closed");
        
    } catch (NotesException e) {
        e.printStackTrace();
    } finally {
        
        // terminate the NotesThread properly
        NotesThread.stermThread();
        
        // remove a the so a NotesThread can be initialized
        // on the Zero thread
        sessions.remove(threadId);
        
        System.out.println("Removed NoteSession for Zero thread : " + threadId);

    }
}

此模型已被证实极具挑战性。有时,当其他请求造成 JVM 崩溃时,NotesThreads 会被正常终止。清单 5 所示的系统崩溃将出现在编程过程中。


清单 5. JVM 崩溃错误内容

#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x60001457, pid=2660, tid=6448
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_12-b04 mixed mode)
# Problematic frame.
# C  [nnotes.dll+0x1457]
#

出现此类错误的原因是对已初始化的 Zero HTTP 线程进行 NotesThread 初始化操作,或尝试终止已初始化 Zero HTTP 线程的 NotesThread 任务。在正确初始化和处理 NotesThreads 以及离开初始化线程之间,我们陷入了两难的境地,但可能会造成 Lotus Domino 服务器的不稳定。基于本文的演示目的,我们选择了后者。可以采取一些相应的措施来解决这种设计问题。您可以扩展 NotesThread 类并将自己的逻辑封装在其中。完成 run() 或 runNotes() 方法后,NotesThread 将被适当处理,但您可能需要实现一些线程来完成非常具体的操作。我们选择的设计方式相当有趣,您可以在 Project Zero 论坛 上发表问题寻求 Project Zero 小组和其他社区用户的帮助。

此处的目的并非阻止您探索 Project Zero 和 Lotus Domino,而是将我们的经验告诉您。本文中所描述的问题可能都有解决方法或已知的技术限制。

还需注意,应用程序将创建一个本地 Notes 会话,但它在访问本地服务器或 Lotus Notes 客户机上的数据时不受任何限制。通过在 getDatabase() 函数中指定 Lotus Domino 服务器名称,您可以更新代码访问远程 Lotus Domino 服务器上的数据库。

有关更多详细信息,请参阅本文稍后的 “使用 Lotus Domino Employees 应用程序” 一节。

创建 IIOP 会话

虽然并未在 Lotus Domino Employees 应用程序中实现,但 IIOP 是 RPC 格式的替代之选。当 Project Zero 应用程序并未运行在拥有本地 Lotus Domino 服务器或 Lotus Notes 客户机安装的服务器中时,IIOP 的作用就会突显出来。放弃本地 Lotus Domino 或 Lotus Notes 安装需求的代价是需要在 Lotus Domino 服务器上运行 DIIOP 任务。DIIOP 任务将促进远程连接访问数据库、视图和文档等内容。

如清单 6 所示,RPC 代码在更新后可便利 IIOP 与 Lotus Domino 的连接。


清单 6. IIOP 连接代码的差异

private static Session createSession(String server, String token) {
System.out.println("Creating Session");

	try {
		// server should be a DNS address or IP		
		Session s = NotesFactory.createSession(server, token);

		System.out.println("Creation successful");

		return s;

	} catch (NotesException e) {
		System.err.println("Creation failed");

		e.printStackTrace();

		return null;
	}
}

注意,惟一的实际变化在于移除了 NotesThread 处理。当您使用 IIOP 时,NotesThread 会话将不再需要。

IIOP 在服务器上引入了新配置考虑:安全性、访问 Lotus Domino 服务器上的 diiop_ior.txt 文件,以及各种端口配置。您还应在确保在 Lotus Domino Server 文档的 Internet Protocols - HTTP 选项卡上选中 “Allow HTTP clients to browse databases” 选项。


图 12. 配置 DIIOP
配置 DIIOP

此设置允许会话获得服务器上的数据库列表??有关 DIIOP 的更多信息,请参阅 Lotus Domino Designer Programming Guide 的 NotesFactory 一节。

访问 Lotus Domino 数据

现在,我们已经使用 Notes 会话建立了 Lotus Domino Employees 应用程序的行为和帮助函数,并开始查询或修改 Lotus Domino 目录。由于 Lotus Domino Employees 应用程序的专注点与用户相关,因此帮助函数将操作 Lotus Domino Person 文档。

举例来说,对 resource /employees 的请求将检索目录中的所有联系方式。此操作等价于获取使用 names.nsf 数据库中的 Person 表单创建的所有文档。清单 7 中的代码演示了此行为。


清单 7. 使用 Lotus Notes 文档集合获取所有员工

public Employees getAllPeople() {
		// conduct a search for people created with the Form. People
		// this is true for all users
		DocumentCollection dc= searchNab("Form=\"Person\"");
		
		// convert the collection into Employees
		Employees contacts= getPeople(dc);
		
		// recycle the document collection
		try {
			dc.recycle();
		} catch (NotesException e) {
			e.printStackTrace();
		}
		
		return contacts;
	}


注意,getAllPeople 函数将发送一个搜索公式给 NAB,以获取所有的 Person 文档,这等同于搜索可以操作 Lotus Domino 数据库的客户机用户。您可以在目录中打开 People 视图并在其中返回 DocumentCollection,而不用打开目录并执行搜索。这种方法允许您更好地利用已有的 Lotus Domino 结构来减少代码和性能开销。它还降低了全文索引目录的需求。

Lotus Domino 数据表示

在之前获取所有员工的检索操作时,所返回的结构是 Notes 对象 DocumentCollection。DocumentCollection 恰如其名;它由一系列 Document 对象组成。Document 对象对应于目录中的实际 Person 文档。为了使数据表示流程清晰可见,我们首先将文档中需要的值复制到新的 Employee 对象中,如清单 8 所示。


清单 8. Document 到 Employee 对象的转换

public Employee(Document doc){
data= new HashMap();
		
	try {
		// verify that the document is a person doc
		if(doc != null &&
			doc.hasItem("Form") &&
			doc.getItemValueString("Form").
				equalsIgnoreCase("Person")){
					
			// pull data as Strings from the person doc
			for(int i= 0; i < Employee.FIELDS.length; i++){
				data.put(Employee.FIELDS[i], doc.getItemValueString(
							Employee.FIELDS[i]));
			}

			notesUrl= doc.getNotesURL();
			
}
	} catch (NotesException e) {
		e.printStackTrace();
		
		notesUrl= "";
	}
}

代码将迭代在 Employee 对象中指定的预先定义的字段名称(如清单 9 所示),并将 Person 文档中相应字段的值复制到 Employee 对象的 HashMap 中。


清单 9. 迭代字段名称

public static final String NAME= "FullName";
public static final String UID= "ShortName";
public static final String FIRSTNAME= "FirstName";
public static final String LASTNAME= "LastName";
public static final String EMAIL= "InternetAddress";
public static final String PHONE= "OfficePhoneNumber";
public static final String PASSWORD= "HTTPPassword";
public static final String ADDRESS= "OfficeStreetAddress";
public static final String CITY= "OfficeCity";
public static final String STATE= "OfficeState";
public static final String ZIP= "OfficeState";

从本质上说,我们在 Employee 对象中模拟了 Document 对象中的名称/值对。在大型系统中,复制实际数据将阻止 Lotus Domino 对象在 JSON 转换流程开始之前被回收或被删除,这有时会造成错误。

将 Lotus Domino 数据转换为 JSON

当 Employee 对象中填充了用户数据,并且需要将它转换为 JSON 并将该 JSON 发送给客户机时,请考虑应用程序的状态。该流程发生在使用请求 employees/[uid] 检索用户时。再一次,Project Zero 极大地简化了这一操作,如清单 10 所示。


清单 10. Project Zero 提供对 JSON 转换的内在支持

// retrieve the Employees Collection by creating a
// NabHelper and requesting all the people
Employees employees= new NabHelper(session).getAllPeople();
				
if(employees != null){
	
// automatically serialize the object to JSON using
	// Project Zero's custom converter
	request.view='JSON'
	request.json.output= employees; 
}

render()

以上代码的关键步骤在于将实际对象作为 JSON 输出提供给客户机。对于简单对象,Project Zero 会使用公有 get 函数自动将对象转换为 JSON。对于比较复杂的对象,您应该使用自定义转换程序定义转换流程。

使用自定义转换程序转换 Lotus Domino 数据

为了使用 request.json.output = object 语法简单地完成转换,我们创建了一个自定义转换程序。对于给定对象,Project Zero 将实例化适当的自定义转换程序将对象转换为 JSON。为实现此目的,我们创建了一个类来实现 IConverter(Milestone 1)或 Converter(Milestone 2)接口。清单 11 给出了这个类的代码。


清单 11. 员工用户转换程序

public class EmployeeConverter implements Converter {

	public Object toJson(Object o) {
		Employee person = (Employee) o;
		JSONObject json = new JSONObject();
		
		// the person document's fieldname value pairs have already been
		// stored as a hashmap when the document was originally read
		// simply convert the contents into JSON
		
		Iterator it= person.getData().
			keySet().iterator();

		while(it.hasNext()){
			String param= (String)it.next();
			json.put(param,
					(String)person.getData().get(param));
		}

		return json;
	}

…

request.json.output 赋值操作中的传入对象将作为 toJson 函数中的参数提供。然后,我们将创建一个 JSONObject 来存储已保存在 Employee 对象中的名称/值对。联系人的 JSONObject 表示如清单 12 所示。


清单 12. Person 文档中的数据的 JSON 表示

{
      "FirstName": "Van",
      "FullName": "CN=Van Staub\/O=IBM",
      "HTTPPassword": "(355E98E7C7B59BD810ED845AD0FD2FC4)",
      "InternetAddress": "vstaub@ibm.com",
      "LastName": "Staub",
      "OfficeCity": "Atlanta",
      "OfficePhoneNumber": "(123) 456-7890",
      "OfficeState": "Ga",
      "OfficeStreetAddress": "4111 Northside Pkwy",
      "ShortName": "vstaub"
}

JSONObject 并不局限于名称/值对。您可以使用字符串、数字、值、数组和其他对象创建复杂对象。举例来说,清单 13 是 Lotus Domino 服务器上的数据库的一个表示。JSONObject 含有一个 JSONObjects 数组(JSONArray),其中含有数据库信息。各个对象还包含一个错误状态和错误消息。


清单 13. Lotus Domino 数据库的一个复杂表示

{
   "databases": [      
      {
         "filename": "names.nsf",
         "filepath": "names.nsf",
         "httpurl": "http:\/\/domino.ibm.com\/__85257350001864E6.nsf?OpenDatabase",
         "message": "",
         "notesurl": "notes:\/\/Domino@IBM\/__85257350001864E6.nsf?OpenDatabase",
         "replicaid": "85257350001864E6",
         "status": 0,
         "template": "StdR4PublicAddressBook",
         "title": "IBM's Directory"
      }, 
      {
         "filename": "webadmin.nsf",
         "filepath": "webadmin.nsf",
         "httpurl": "http:\/\/domino.ibm.com\/__85257350001883E1.nsf?OpenDatabase",
         "message": "",
         "notesurl": "notes:\/\/Domino@IBM\/__85257350001883E1.nsf?OpenDatabase",
         "replicaid": "85257350001883E1",
         "status": 0,
         "template": "",
         "title": "Domino Web Administrator (7)"
      }
   ],
   "message": "",
   "status": 0
}

配置自定义转换程序

实现了自定义转换程序之后,您需要连接对象和转换程序。为此,可以更新 Project Zero 的配置文件 zero.config。要将转换程序连接到对象,可以使用以下语法:

[/config/json/converters/object=convert_class

举例来说,要连接 Employee 对象与员工转换程序,可以使用以下配置:

/config/json/converters/com.ibm.devworks.Contact=com.ibm.devworks.json. EmployeeConverter

如果您决定为 Lotus Notes 类本身实现转换程序,务必要注意对象的返回类型。如前所述,您可以创建各种类型的 Sessions 来访问 Lotus Domino 数据。根据会话的连接,Lotus Domino 数据的返回类型可能会有所不同。要确保行为的一致性,可以建立自定义转换程序并在其中包含相同 Lotus Domino 资源的各种类型。请参见清单 14。


清单 14. 不同类型的 Lotus Domino 对象需要一个转换程序o

config/json/converters/lotus.domino.Database=
com.lotus.rest.json.converters.DatabaseConverter
config/json/converters/lotus.domino.local.Database=
com.lotus.rest.json.converters.DatabaseConverter
config/json/converters/lotus.domino.cso.Database=
com.lotus.rest.json.converters.DatabaseConverter

使用 Lotus Domino Employees 应用程序

要使用 Lotus Domino Employees 应用程序,您需要在 Lotus Domino 服务器上安装 Eclipse 和 Project Zero 插件。安装好这些插件之后,遵循以下步骤开始使用应用程序:

  1. 在 Eclipse 中,选择 File - Import - General - Existing Projects into Workspace,然后选择 Select Archive File 选项。
  2. 单击 Browse 按钮找到 employee.domino.demo.-all-1.0.zip 文件,然后单击 OK 按钮。
  3. 单击 Finish 按钮导入所选项目。
  4. 选择 Run - Run As - Project Zero Application,创建一个新的运行时配置。启动项目后,使用控制台视图上的 Stop 图标停止应用程序。
  5. 选择 Run - Run - Project Zero Application - employee.domino.demo,编辑运行时配置。分别编辑 Arguments 和 Environment 选项卡上的 java.library.path 和 PATH 变量,并参考本文的 “配置 Project Zero 的 RPC 会话” 一节。单击 Apply 按钮,然后关闭程序。
  6. 打开 config/zero.config 文件。
  7. 更新 config/domino/rest 部分中的设置,应用到您的 Lotus Domino 服务器。请参见清单 15 中的代码。


    清单 15. 配置 Lotus Domino Employees 应用程序
    						
    # mail directory of the Domino server relative
    # to the data directory
    # during contact creation a mail file is also created
    
    /config/domino/rest/mailDirectory = "mail"
    
    
    # field that uniquely identifies people
    # this should conform. to the value passed using REST
    # for example, /employees/[uid] is /employees/vstaub
    
    /config/domino/rest/employeeSearchField = "ShortName"
    
    
    # certifier ID password
    
    /config/domino/rest/certIdPassword = "password"
    

  8. 再次,选择 Run - Run As - Project Zero Application。运行应用程序时将出现一个类似于 “C:/Eclipse_ProjectZero/Workspace/employee.domino.demo running on port 8080” 的消息。
  9. 请求受 Lotus Domino 保护的资源,如 names.nsf。
  10. 登录 Lotus Domino 服务器。
  11. 请求 http://:8080。
  12. 单击 List Employees 按钮开始。

注意,names.nsf 必须为全文索引。您可以使用 Lotus Notes 客户机通过 names.nsf 数据库的 Properties 框中实现此目的。Firefox 客户机已经为 Dojo 部件生成了最稳定的客户端应用。如果一切顺利,您将在浏览器中看到如图 13 所示的 Lotus Domino Employee 应用程序。


图 13. Lotus Domino Employees 应用程序的成功部署

日志记录已经作为 System.out 和 System.err 语句实现。如果出现问题,请查看控制台日志中的信息。

一般技巧

使用 Eclipse 调试。在调试运行中应用程序的有用信息时,检查 Global Context 参数变量。使用调试方法确认了我们的猜测,一些线程用于促进 HTTP 请求,并且各线程都要求 Lotus Notes 初始化。

参阅文档。从 Milestone 1 变更为 Milestone 3 需要移植原始代码。了解已安装的版本和所参阅的任何示例的版本。

从一个示例开始。尝试新特性或集成,方法是从 Project Zero 小组提供的一个工作示例开始。

在单独的应用程序中测试代码。Bug 可能会成为 JVM 或 Project Zero 之间产生细微差别的一个因素,而不一定是由代码产生的。这种方法可帮助您理解该问题并适应使用 Project Zero 的工作方式。

未来计划

本文演示的概念有一个具体的用例;但是,其底层模型是使用 Project Zero 对 Lotus Domino 进行资源建模的一个例子。因此,您可以使用 JSON 表示所有的 Lotus Domino 数据并极大地增强已有应用程序的可用性。一些通用思想可用于编写 Ajax 友好的 IBM Lotus Domino Web Access 页面,用于自动检索用户的邮件文件并将它动态地显示在页面中。另一个想法是在 IBM Websphere Portal 环境中创建响应更快的 Lotus Domino 视图和文档的清单。Project Zero 可以轻松地将新的 Web 2.0 理念结合到已有的 Lotus Domino 概念中,这是令人惊叹不已的。

结束语

借助 Project Zero,我们将一个简单的 Lotus Domino 数据库转换成为了一个功能性的 RESTful 应用程序。我们在之前已经看到,在 Project Zero 框架中结合使用 Groovy 等脚本语言可以极大地改进开发流程。最后,我们查看了基于 REST 的 Domino 应用程序的结果。由于 REST 和 Web 2.0 概念的的普及,任何 Lotus Domino 开发人员都可利用已有概念使用 Project Zero 开发和实现 RESTful Domino 应用程序。在此过程中,您可以通过各种创新方式扩展 Lotus Domino 应用程序的使用。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14751907/viewspace-586489/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/14751907/viewspace-586489/

Lotus Domino WEB 开发技术积累-DOC(313页) 1. 选取视图的列的内容 @Trim @DbColumn 6 2. 隐藏判断常用的命令 6 3. 判断当前用户是否是“某个组”的成员,然后来显示和隐藏 6 4. 在Lotus Domino 中显示图 6 5. 链接JS文件 6 6. 删除文档的方法 7 7. $$return 域的使用 8 8. 将表单设计为视图或导航器模板 9 9. 为 Web 定制“表单已处理”确认信息 10 10. 定制出错信息 11 11. $$HtmlHead几种常用的技巧 11 12. Domino Designer 模板表 12 13. 角色判断 13 14. 判断文档是否正在被修改 13 15. 在只读的方式下返回($$return 13 16. 刷新表单 14 17. 怎样在文档里存照片? 14 18. 后台lotusscript如何取得前台表单中复选框所选择的项目列表(b/s结构) 15 19. 试图的列公式:附件下载 15 20. 有没有好一点的分页处理代码 16 21. 同一用户重复登录 18 22. Return to sender 19 23. Agent to copy values from 1 form to another 在同一个数据库中进行 22 24. 超越OLE – 通过COM结合MS Office与Notes应用 23 25. 读写关系数据库资料 28 26. 视图---excel,表单---word 32 27. 关于Web上的检索问题 35 28. 如何使用Notes与关系数据库进行信息交互? 37 29. 如何在IE里面实现notes中的 对话框列表? 39 30. LotusDomino环境下编写Web浏览器多数据库检索程序 40 31. WINAPI函数 44 32. 用PowerBuilder访问Lotus Notes数据库 55 33. 如何在表单中加入计数器 58 34. 实现两个数据库间的数据追加 C/S 结构 60 35. 如何防止他人使用旧id和旧口令访问Domino服务器? 61 36. 在你的WEB站点上使用DOMINO群集 62 37. 在你的DOMINO WEB站点中插入.SWF文件 73 38. DOMINO R5的域搜索功能在WEB上的实现 77 39. Display Rich Text fields in a view 86 40. Auto-Launch a file attachment 87 41. Showing a response count without showing the responses 89 42. 常用的几个按钮收集 91 43. 在WEB上从视图删除文档技巧 93 44. 在Domino Designer中使用XML数据 96 45. 在Domino Designer上执行XML 100 46. Show single category view, the next stage 107 47. Checkboxes in a list box 108 48. Formatting a Notes view in HTML table for WEB 109 49. Jump to the end of a view (web agent) 111 50. Disabling actions until a page finishes loading 114 51. Web-based, fully customizable search 115 52. 从复选框中删除文档Deleting selected docs on Web 120 53. Debugging LotusScript Agents 121 54. Displays the contents of the Subject field in the first document in theExamples view. 124 55. Example: GetLastDocument method 125 56. Examples: GetNextDocument method 125 57. Example: GetFirstDocument method 126 58. Examples: FTSearch method 127 59. Examples: DeleteDocument method 128 60. Example: Deleting a document 129 61. Example: Creating a document 129 62. Examples: Locating documents within a view or folder 130 63. Example: Adding a document 135 64. Export to Excel 136 65. 连接ODBC 138 66. 特效 140 67. notes和Excel交换数据 141 68. NOTES的ODBC:(LS:DO) 142 69. Managing JavaScript "popup" windows 第一稿 144 70. HEAD元素使用集锦 147 71. 主页javascript特效19则 148 72. 关于创建、删除、编辑、打开和保存文档的 URL 命令 156 73. Domino URL 命令 158 74. 在打开有下面这段代码的页面时将会跳出一个468x60大小的小窗口 160 75. javascript的容错脚本 161 76. Web search with JavaScript 162 77. 如何防止他人使用旧id和旧口令访问Domino服务器 164 78. Fixing the Domino CheckBox Bug 165 79. Managing JavaScript "popup" windows 172 80. Quick, easy, foolproof field level help 175 81. Quick edit document link 176 82. Managing JavaScript "popup" windows 178 83. Svg: Pie-Eyed 181 84. Recebt Entries 182 85. Xin Calendar Mods 183 86. 答复文档 186 87. 公式语言 187 88. Resuable way to get URL parameters into fields 199 89. JSHeader 使用 201 90. JavaScript 帮助 201 91. Examples: Collecting documents by searching 207 92. 关于DOcumentContext 的属性 209 93. About data types 关于lotus Domino 的数据类型 210 94. CLng function 212 95. Using the DOM to replace "No documents found" 213 96. What you need and want to know about errors 217 97. Processing multiple documents from a view 221 98. Forcing attachments to always download 225 99. ODBCExample: GetValue method 247 100. ODBCResultSet class 248 101. Create a "Login" anchor link 251 102. 分类视图的开发技巧 253 103. 公式语言 255 104. Copy documents from one database to another 267 105. 定制搜索表单 268 106. UserName的属性及使用 275 107. Dynamic Content for Popup Windows 277 108. Shortcut when printing from a Java Agent 278 109. Lotus Script: Write # statement 279 110. Lotus Script: Input # statement 280 111. 使用代理生成 XML 284 112. 使用视图生成 XML 286 113. 执行算术运算 288 114. Keep URLs simple by making them relative 292 115. Quick, easy, foolproof field level help 294 116. Hiding attachments (without noscript tag!) 295 117. Listing search results in groups 296 118. 如何在表单中加入计数器? 300 119. 怎样限制一个WEB用户只有登陆才能使用数据库 302 120. Complete control when printing HTML from an agent 304 121. Simple multi-lingual forms using Domino 306 122. Stop double form submissions 308
第1章 Domino Web开发综述 1 1.1 为什么使用Domino 1 1.2 Domino是怎样运行的 1 1.2.1 Domino与传统数据库的区别 1 1.2.2 DominoWeb 2 1.3 开发部件 2 1.4 其他工具 3 1.5 简单的Domino Web软件例子 10 参考信息 14 本章小结 14 第2章 使用表单 16 2.1 关于表单 16 2.2 在表单中使用公式 17 2.2.1 数组和多值域 18 2.2.2 公式的类型 18 2.2.3 例子:一个组合框域 20 2.2.4 例子:$$Return域的公式 22 2.3 在表单中使用Web元素 22 2.3.1 嵌入Web元素 22 2.3.2 创建特殊用途的模板表单 22 2.3.3 例子:在$$View Template Default 表单中嵌入导航器 23 2.3.4 例子:动态嵌入式导航器 24 2.4 在表单和表单对象中使用HTML属性 25 2.4.1 <META>标记的例子 26 2.4.2 例子:RTF文本域的属性 27 2.4.3 例子:cookie 27 2.5 使用表单操作按钮 28 2.6 使用热点 30 2.7 在表单内使用HTML 31 2.7.1 例子:单个类视图 31 2.7.2 例子:显示附属图形文件 36 2.7.3 例子:把文本域显示为文本区域 39 2.8 在表单中使用CGI变量 40 2.9 表单和搜索 42 2.9.1 定制视图搜索表单 43 2.9.2 例子:定制搜索界面 44 2.9.3 定制Site Search表单 47 2.9.4 定制Search Results表单 47 2.9.5 例子:对搜索结果表单的定制 48 2.10 定制表单提交按钮 49 2.11 使用隐藏域 49 2.12 把RTF文本显示为一个小应用程序 50 参考信息 51 本章小结 51 第3章 使用视图进行工作 54 3.1 关于视图 54 3.2 视图和Web 55 3.3 使用选择公式 56 3.4 使用视图列公式 57 3.5 使用表单公式 57 3.6 使用视图图标 58 3.7 创建视图操作按钮 59 3.8 使用单个类视图 60 3.9 在视图中使用HTML通用文本 62 3.9.1 改变行的格式 63 3.9.2 在视图中显示Java小应用程序和图像 63 3.9.3 HTML通用文本 64 3.9.4 改变视图连接的动作 66 3.9.5 控制视图连接的另外一种方式 68 3.9.6 例子:在视图中使用java Script 68 3.10 在表单中使用视图 70 3.10.1 在表单中嵌入视图 70 3.10.2 创建视图模板 70 3.10.3 例子:使用表单在视图中添加 功能 71 3.10.4 例子:使用视图在表单中添加 功能 73 3.10.5 例子:创建多个类的视图 76 3.11 在小应用程序表单中显示一个视图 79 参考信息 80 本章小结 80 第4章 使用帧结构、大纲和其他设计 元素 82 4.1 简介 82 4.2 在帧结构中设计 82 4.2.1 帧的不利之处 83 4.2.2 使用帧结构集设计元素 84 4.2.3 使用<FRAMESET>标签 88 4.3 使用大纲 94 4.3.1 同时使用帧和大纲 95 4.3.2 显示大纲小程序 97 4.4 使用其他的设计元素 97 参考信息 101 本章小结 101 第5章 编写JavaScript 103 5.1 简介 103 5.2 开始编写JavaScript 104 5.3 把JavaScript添加到Domino的表单中 106 5.4 验证域:Expense Report表单 107 5.5 计算域的值:Expense Report表单(续) 109 5.6 显示域相关的帮助 110 5.7 控制帧的使用 112 5.8 填充动态列表框 114 5.9 例子:动态下载图像 117 5.10 例子:在一个滚动按钮中预先下载 图片 119 5.11 例子:显示对话框 121 5.11.1 Order Form表单 123 5.11.2 Select Parts表单 124 5.11.3 Read-Only Order Form表单 127 5.11.4 Orders视图 127 5.12 例子:操纵cookie 127 5.13 例子:ActiveX对象脚本 128 5.14 例子:Domino产生的JavaScript 133 参考信息 137 本章小结 138 第6章 编写LotusScript 139 6.1 简介 139 6.2 关于LotusScript Web代理 140 6.3 激活一个代理的URL 141 6.4 在LotusScript中编写WebQueryOpen 代理 142 6.4.1 简单的LotusScript WebQueryOpen 代理 142 6.4.2 查询数据库 144 6.5 在LotusScript中编写WebQuerySave 代理 146 6.5.1 简单的LotusScript WebQuerySave 代理 146 6.5.2 在表中显示ODBC搜索结果 147 6.6 在LotusScript代理中使用CGI变量 150 6.6.1 QUERY_STRING代理 150 6.6.2 HTTP_COOKIE代理 154 6.7 在基于Web的工作流中使用LotusScript 157 6.8 在LotusScript代理中使用小应用程序 161 参考信息 170 本章小结 170 第7章 Java应用程序 171 7.1 使用Java语言 171 7.2 Domino 4.6及以上版本的Java应用程序 172 7.2.1 例子:SendMemo.java 173 7.2.2 例子:SendMemo2.java 175 7.2.3 Java接口 175 7.2.4 例子:SendMemo3.java 176 7.2.5 使用GUI组件 177 7.2.6 例子:Send Memo4.java 177 7.2.7 多线程的例子:ListGroups应用 程序 179 7.3 Domino 5的Java应用程序 185 7.3.1 简单例子:CorbaApplication.java 186 7.3.2 GUI例子:CorbaApplication2.java 186 参考信息 189 本章小结 189 第8章 Java代理 190 8.1 简介 190 8.2 关于Java Agents 190 8.3 编写4.6版的Java代理程序 191 8.3.1 简单Java代理:Simple Agent.Java 191 8.3.2 多线程代理程序:NotesGuiAgent. java 196 8.3.3 Java Web代理程序 199 8.4 在R5中编写Java代理 226 参考信息 230 本章小结 231 第9章 使用Java小应用程序 232 9.1 简介 232 9.2 Java小应用程序Domino 233 9.3 简单例子:HelloUser.java 234 9.4 声音例子:AudioApplet.java 236 9.5 使用 LiveConnect:Java_JS.java 241 9.6 LiveConnect和标准的Domino小应用 程序 244 9.7 编写小应用程序更容易的方法: Lotus BeanMachine 245 9.8 使用eSuite 247 9.8.1 什么是eSuite 247 9.8.2 eSuite和Domino 248 9.8.3 eSuite Workplace Desktop 248 9.8.4 eSuite小应用程序 249 9.8.5 应用功能的局限性 251 9.8.6 eSuite InfoCenter简介 252 9.8.7 eSuite Devpak 252 9.8.8 DevPak组件 253 9.9 InfoBus技术介绍 253 9.9.1 InfoBus例子 254 9.9.2 eSuite/InfoBus例子 255 参考信息 257 本章小结 258 第10章 编写CORBA小应用程序 259 10.1 简介 259 10.2 什么是CORBA 259 10.3 关于lotus.domino软件包 259 10.4 例子:Corba Text 1.java 260 10.5 例子:ResumeApplet.java 264 10.6 显示数据图表:SalesChartApplet.java 270 10.7 使用两种方式发送数据: AgentControlPanel.java 274 10.8 CORBA小应用程序还不能实现的 功能 279 参考信息 280 本章小结 280 第11章 编写Java小服务程序 281 11.1 什么是小服务程序 281 11.2 为什么在Domino中使用小服务程序 281 11.3 启用小服务程序支持 282 11.4 编写小服务程序 283 11.4.1 简单的HTTP GET小服务程序: StupidServlet 283 11.4.2 简单的HTTP POST小服务程序: JDBCQueryServlet 284 11.4.3 使用链接缓冲区的JDBC小服务 程序 289 11.4.4 Cookie-Setting Servlet 293 11.4.5 小服务程序和Netes Java类 298 11.4.6 最后一点说明 299 参考信息 300 本章小结 300 附录 Domino URL 301
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值