转自IBM
http://www-900.ibm.com/cn/support/nav/200103/p57.shtml
一、电子商务与内容管理(Content Management)
|
----Domino R5对Java Servlet的支持使您在开发Notes应用时有了更多的选择。例如,您可以使用Servlet代替Domino代理(Agent)访问Domino对象,完成服务器端的处理。
|
----本篇文章提供了有关Domino Servlet 的开发和运行配置,包括:
|
----Servlet 的特点,与Agent的区别,Domino对Servlet的支持
|
Domino服务器运行servlet的配置
|
----Servlet的开发,通过两个servlet例子,介绍如何使用Servlet访问Domino对象。
|
----本篇文章设想读者熟悉JavaScript,Java, Servlet, 了解Domino应用程序设计。
|
Servlet特点以及与Agent的区别
|
----Servlet是运行在服务器上的Java程序,提供类似于CGI应用和Domino Agent的功能。Servlet的主要优点是只装载入内存一次,而Agent和CGI程序是每次调用时都需装载入内存。Sservlet一次装载入内存后,以后所有调用都使用该实例。例如,针对连接数据库的任务,您可以选择Servlet来保持一个永久连接传输数据,提高运行效率。
|
----尽管Agent和Servlet提供类似功能,但它们的实现差别很大。Agent存在于Domino数据库而Servlet在文件系统下。这立即带来了两个问题:分布和安全。Agent可以充分利用它所在的数据库,因此,可通过复制分布到其它服务器。同样,Domino安全模式控制Agent的访问。相反,Servlet存在于文件系统,因此由服务器、文件和目录安全来控制Servlet的访问。Servlet缺省是以服务器安全权限来运行,但也可以某一特定Internet用户名字和口令来运行。最后,除非使用WinNT目录复制,否则您必须拷贝或安装Servlet到其它需要的服务器。
|
关于Servlet开发环境JSDK
|
----标准Domino Designer的开发环境并不支持Servlet开发,因此您必须使用第三方IDE或SUN命令行JDK开发Servlet代码。
|
----开发Servlet所需的JSDK可从SUN免费得到,另外JSDK是Domino安装的标准部分,jsdk.jar位于D安装根目录。例如,您的Domino服务器安装在D盘的r5server目录下,则JSDK在D:\r5server\jsdk.jar。
|
----注意:Jar文件是标准JAVA文件的压缩。类似于Winzip,PKZip或Windows CAB文件。
|
----Domino 4.6.x 支持 JSDK 1.x. Domino 5.0 从 5.0.2b 以后版本支持 JSDK 2.0。最新版本支持情况请参考随软件的产品发布信息。
|
设置Domino服务器运行Servlet
|
----Domino R5 有自己的Servlet管理者,但也可使用第三方Servlet引擎,推荐使用IBM WebSphere。Domino通信录的服务器文档含有Servlet设置部分。具体设置是:
|
----打开Domino通信录names.nsf数据库——打开“服务器文档”——进入“Internet协议”项——进入“Domino Web引擎”项——编辑“Java Servlets”选项组,如下图:
|
|
|
----这些选项的描述如下:
|
- Java servlet 支持-------------启用/禁用。可选项是:禁用、Domino Servlet 管理者和第三 方Servlet支持。
- Servlet URL 路径-------------访问Servlet的URL,例如/servlet。
- 类路径 ---------------------Servlet所在的目录,相对于Domino 数据目录。例如domino\servlet,实际是Domino 数据目录下的domino\servlet。
- Servlet 文件扩展------------URL文件扩展名,用来告诉Domino它是一个Servlet,以逗号分隔。
- 会话状态跟踪----------------启用/禁用指示Servlet管理者是否将中止空闲的会话。
- 空闲超时时间----------------一个空闲会话在被中止前的时间(分钟)。此参数只有在启用“最大活动会话”时才有效。
- 最大活动会话----------------最大活动Servlet会话数。
- 会话持续----------------------启用/禁用。指示会话信息是否存入磁盘。
|
----一旦Domino服务器配置成“启用”Servlet,以下与Servlet有关的行将出现在Domino数据目录下的Domino配置文件(domino.cnf) 中:
|
# Java Servlet Settings ServerInit servlet:ServletInit d:\r5server\Data Service /servlet/* servlet:ServletService* ServerTerm servlet:ServletTerm
|
----Domino 支持JVM和Servlet Manager(包括Domino自己的和第三方的)。当Servlet“启用”时,JVM在Domino HTTP服务器启动之前装载;如果使用Domino Servlet Manager,在JVM装载之后,Domino HTTP服务器启动时装载Servlet;如果使用第三方Servlet Manager,则只装载JVM。
|
----用户从浏览器访问servlet 时,URL为:http://myserver/servlet/ servletname。例如,输入 http://myserver/servlet/HelloWorld 运行 HelloWorld servlet 。
|
| ----WEB服务器启动时装载Servlet,此刻后Servlet将在内存中,开始工作。但是,Servlet代码改变后,Domino HTTP服务器必须退出并重新启动,新代码才会起作用。 |
Servlet properties 文件
|
----Servlet可由两种方法装载:第一种是Servlet Manager 在HTTP启动时按servlets.properties 文件指定的参数装载Servlet,第二种是客户第一次调用Servlet时装载Servlet。Servlet在HTTP任务停止运行时从内存被清除。
|
----您应当尽可能使用第一种。在HTTP任务启动时就装载Servlet,以后用户请求不用再装载,相应时间和延迟就小。
|
----servlets.properties是一个TXT格式的配置文件,用来指定装载Servlet时的标准参数,位于Domino数据目录,例如:D:\r5server\data\servlets.properties。您可以使用TXT编辑器创建它。
|
----servlet properties 文件包括Servlet别名,初始化参数,URL扩展映射,WEB服务器启动时需装载的Servlet。
|
----本篇文章设想读者熟悉JavaScript,Java, Servlet, 了解Domino应用程序设计。
|
语法如下:
|
----Servlet 别名------servlet.<alias-name>.code=<class-name> ----初始化参数------servlet.<alias or class name>.initArgs=<name1=value1>,<name2=value2> ----Servlet代码中可以使用ServletConfig.getInitParameter方法访问这些数据。 ----URL 扩展映射---servlet.<alias or class name>.extension=<extension> <extension> ... ----启动时装载------servlets.startup=<alias or class> <alias or class> ...
|
----以下是一个servlets.properties 文件,这里指定Test为HelloWorld.class Servlet的别名,指定了初始化参数,启动时装载。
|
----# Example servlets.properties file ----servlet.Test.code = HelloWorld ----servlet.Test.initArgs = 1, 2, 3 ----servlets.startup = Test
|
----有关Servlet配置文件经常出现的错误有:
|
- 文件目录放置错误,它必须是在您的Domino数据目录下。
- 文件扩展名错误,许多编辑器例如Notepad使用TXT扩展名
- 使用错误文件名,文件名必须是servlets.properties
- 大小写错误,文件名如同Servlet名字是大小写敏感的。
|
Domino Servlet开发示例
|
----Servlet只装载入内存一次。装载时运行init 方法,以后每一次客户请求Servlet时执行service 方法,按照用户的请求执行doPost 或 doGet方法。
|
| Servlet结构 |
----编写Servlet,使用以下Servlet类:
|
----Javax.servlet.http.HttpServlet ----Javax.servlet.GenericServlet
|
----定义方法描述Servlet功能, 经常用到的方法如下:
|
----doGet() and doPost() 处理 GET 和 POST 请求. ----getServiceInfo() 提供 servlet 描述 ----init() servlet 初始化代码 ----service() 处理请求
|
----HTTP请求可有两种:get 和 post。get方法在URL结尾附加信息,可从环境变量query_string中得到;post以“变量名/变量值”形式发送信息。
|
----Servlet代码开发时,get或 post方法使用到JSDK中两个包:javax.servlet和javax.servlet.http。代码中需引入它们。
|
----在您编译servlet 代码之前, 使用到的servlet 类需要增加到 CLASSPATH 环境变量中。然后您可以用您喜欢的JAVA编译器编译servlet 代码。
|
使用Servlet访问Domino对象示例1
|
----下面一个例子是Servlet和Domino的集成,Servlet访问Domino通信录中的对象。
|
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import lotus.domino.*; public class Example_2 extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{ res.setContentType("text/html"); PrintWriter toBrowser = res.getWriter(); toBrowser.println("<HTML"); toBrowser.println("<HEAD>"); toBrowser.println("<TITLE>Example 2</TITLE>"); toBrowser.println("</HEAD>"); toBrowser.println("<BODY>"); toBrowser.println("<H1>Example 2</H1>");
|
----调用Domino对象的代码必须包含在try/catch 块中(见以下一段代码),首先创建一个NotesThread 对象,然后创建一个新的会话对象。此处创建会话对象的方法中没有参数,即是用服务器的ID访问Domino对象,您也可指定使用某一用户的Internet用户名和口令作为参数,用此用户身份访问Domino对象,从通信录(names.nsf) 数据库的People 视图取得第一个文档。
|
try { NotesThread.sinitThread(); /*创建NotesThread对象 Session s = NotesFactory.createSession(); /*创建新会话对象 Database db = s.getDatabase("","names.nsf"); /*访问通信录数据库 View vw = db.getView("People"); /*访问视图People Document doc = vw.getFirstDocument(); /*获得第一个文档
ToBrowser.println(db.getTitle()); /*获得数据库标题 toBrowser.println("<TABLE>"); while (doc != null) { toBrowser.println("<TR><TD>"); toBrowser.println(doc.getItemValueString("LastName")); toBrowser.println("</TD></TR>"); doc = vw.getNextDocument(doc); /*获得下一个文档 } toBrowser.println("</TABLE>"); vw.recycle(); db.recycle(); s.recycle(); } catch (NotesException n) {
|
----toBrowser行代码发送数据库标题给请求的客户端浏览器。while (doc!=null) 行开始循环搜索视图中所有文档,将文档中的“Last Name ”值显示在浏览器上,完毕后释放Domino对象使用得内存。
|
----最后,显示任何Notes 错误并在finally 块中中止NotesThread对象。
|
System.out.println("Exception ID: " + n.id); System.out.println("Exception description: " + n.text); } finally { NotesThread.stermThread(); } toBrowser.println("</BODY></HTML>"); } }
下图显示了运行结果。 | |
|
|
使用Servlet访问Domino对象示例2
|
----前面是Servlet与Domino对象的结合,下面一个实例是Servlet与Domino表单的结合。我们先分析代码,然后跟踪表单的建立过程。
|
----下面代码是一个Servlet处理经表单确认后传送到服务器的变量/变量值。变量数值从表单中取得,用来向Domino数据库中添加文档。代码从标准行开始,然后从表单中取出FName, LName, Email和 Phone字段值。
|
import javax.servlet.*; import javax.servlet.http.*; import lotus.domino.*; import java.io.PrintWriter; import java.io.IOException; public class Example_3 extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter pw = res.getWriter(); pw.println("<html>"); pw.println("<head>"); pw.println("<title>Example 3</title>"); pw.println("</head>"); pw.println("<body>"); pw.println("<h1>Thank you!</h1>"); String fname = req.getParameter("FName"); /*获得表单中的字段值 String lname = req.getParameter("LName"); String email = req.getParameter("Email"); String phone = req.getParameter("Phone");
|
----下一步,正如前一个Servlet例子,创建一个Domino对象的会话,访问Domino通信录。这里我们只处理数据库能找到的情况。
|
try { NotesThread.sinitThread(); Session s = NotesFactory.createSession(); Database db = s.getDatabase("","names.nsf"); if (db != null) {
|
----然后创建一个新文档,设置新文档的表单值,用我们取得的变量数值作为新文档中字段的值。
|
Document doc = db.createDocument(); /*创建一个新文档 doc.replaceItemValue("Form", "Person"); /*使用表单Person doc.replaceItemValue("FirstName", fname); doc.replaceItemValue("LastName", lname); doc.replaceItemValue("OfficePhoneNumber", phone); doc.replaceItemValue("MailAddress", email);
|
----然后我们保存文档,释放文档,数据库和会话对象占用的系统资源。(会话对象释放之前,如果数据库找不到,将出现错误信息。)
|
doc.save(true); doc.recycle(); db.recycle(); } else { pw.println("An error was encountered."); } s.recycle(); }
|
----最后,我们处理与Domino有关的exception,中止线程,显示信息到浏览器。
|
catch (NotesException n) { pw.println("Notes Error: " + n.id); pw.println("Description: " + n.text); } catch (Exception e) { e.printStackTrace(); } finally { NotesThread.stermThread(); } pw.println(fname + " " + lname + " has been registered."); pw.println("</body></html>"); } }
|
----现在注意Domino表单建立过程。
|
|
|
----上图是 Domino Designer 表单设计窗口,在标单设计中增加一个新的 HTML 标签指定执行该Servlet,增加一个 Submit 键,点击表单中的 Submit 键,执行 Javascript 代码确认表单,执行该Servlet。
|
----以下是HTML代码,位于表单的顶部,将该表单重定向到Servlet:
|
[</form> <form name="NotesNetExample" action="http://your_server_name/servlet/Example_2">]
|
----这里指定NotesNetExample作为表单名,当用JavaScript访问表单的元素或表单确认时将用到此名字。action中指示表单确认时执行什么。
|
----下图在IE中显示了该表单的调用,输入用户的FirstName,LastName,OfficePhoneNumber,MailAddress后,点击表单中的Submit 键,表单确认时数据将发送到服务器,执行Servlet,登记此用户。
|
|
|
结论
|
----Servlet和 Agent各有其特点,选择Servlet还是Agent有时取决于开发人员。如果开发人员有很多WEB开发经验或您希望使用WebSphere的强大servlet manager,您可选择Servlet;反之有经验的Domino开发人员可能选择Agent。
|
----Java servlets 使您的 Domino 应用更强大。 servlets 增加服务器端功能, 例如保持应用间交换数据的连接。另外,servlets的特性是线程安全代码,支持网络访问,内存自动管理。
|