IBM 操作lotus notes

http://www.ibm.com/developerworks/cn/lotus/domino-wps/

2009年9月04日

LotusNotes/Domino和WebSpherePortal是IBMLotus家族中的两大产品。本文将向读者介绍一个WebSpherePortal与LotusNotes/Domino集成的实例-如何创建一个迷你型的日历Portlet。该Portlet能够从LotusDomino中获取用户的会议数据并将其显示出来,其大小可以改变。用户还可以通过显示出来的会议记录访问其在iNotes上的具体内容。

实例场景

本文将向读者展示一个WebSpherePortal与LotusNotes/Domino集成的实例--创建迷你型日历Portlet,主要有以下功能:

可变化大小。

能够从LotusDominoServer获取用户的日历数据。

点击日历上某一日期,显示当日的会议邀请记录列表。用户点击列表上的任一条目可以在iNotes上打开该条目的详细情况。

读者至少需要拥有LotusDominoServerV7以上,WebSpherePortalV6以上,并完成Portlet与DominoServer之间单点登陆的配置。

关于Portlet与DominoServer之间的单点登陆,在文章IBM/LotusDomino与WebSpherePortal:单点登录中作了具体的讲解。

如果实际客户环境使用LDAP服务器作为DominoDirectory,读者需要配置DominoServer和IBMWebSpherePortal,使得LDAP上的用户能够登陆IBMWebSpherePortal。

由于WebSpherePortal和LotusDomino之间的单点登录是通过一种称为轻量级第三方认证(LTPA)的机制来实现的。因此,还需要配置WebSpherePortal和Domino之间的LTPA关系。这些在WebSpherePortalInfocenter上都有详细的文档,读者可以参考这些材料完成配置。

下面将介绍该实例的原理图,如图1所示。部署在WebSpherePortal上的Portlet,显示一个日历,并通过DIIOP去访问DominoServer得到选定的日期的会议邀请等数据,并在Portlet上显示出来。

图1.实例原理图

回页首

创建日历

可能大家都知道,用JavaScript创建一个日历,简单而快捷。由于在互联网上相关的实例和讲解众多,这里我只是简单的介绍一下日历实现的主要思想。

首先创建一个7×7 的表格,第一行填充[星期一,…,星期天],如图2所示。然后按照下面的规则填充表格单元。

得到该月1日是星期几(假如是第X列),然后从第2行第X列开始填充[1,2,…,Y](假如该月有Y天)。

填充第2行第1列到第X-1列。

填充剩下的表格单元。

图2.日历示意图

各个表格单元的属性可以通过样式文件来显示,例如周末用红色背景,今天用白色背景并加粗等等。

回页首

Portlet与DominoServer之间的通讯

此实例一个重要的功能是能够获取DominoServer上的会议记录。在我们的实例当中,我们通过DIIOP访问Domino。因此,我们必须确保所使用的DominoServer启动了DIIOP服务。具体方法是:打开Domino安装目录下的notes.ini,将DIIOP到ServerTasks中,保存文件并重启DominoServer。

下面介绍如何获取DominoServer上用户的会议邀请等。前文已经提到,我们的应用中,一个重要功能是对SSO的支持。用户登陆了WebSpherePortal之后,我们需要根据WebSpherePortal上的登陆信息找到用户在DominoServer上的信息(MailServer和DIIOP端口是用户单独配置的,具体见创建Portlet小节),最后获取DominoServer上该用户的会议邀请纪录,这里主要包含几个重要的步骤:

获取LTPAcookie信息。清单1中变量sessionToken存储的值是LTPAcookie信息,将作为方法getItemByDateUsingLTPA(见清单3)的第二个参数来获取会议邀请纪录。

获取用户的Notes账号。清单3中开始部分根据LTPAcookie信息获取SessionnotesSession,然后根据语句notesSession.getUserName()来获取用户的NotesID。

获取用户的邮件在服务器上存放位置。一旦获得用户NotesID(DominoServer由用户自行配置),我们就可以通过清单2获取用户的邮件存放位置,返回的结果类似于“mail/test.nsf”。

获取用户的会议邀请纪录。清单3演示了如何通过LTPA信息来获取用户会议邀请条目。其中,CalendarItem存放的数据结构如清单4所示。

清单1.获取LTPAcookie信息

Cookie[]cookies=null;

StringsessionToken=null;

cookies=renderRequest.getCookies();

if(cookies!=null){

for(inti=0;i<cookies.length;i++){

if(cookies[i].getName().equals("LtpaToken")){

sessionToken=cookies[i].getValue();

break;

}

}

}

清单2.获取用户邮件存放位置

publicstaticStringgetMailFile(SessionnotesSession,

StringnameServer,Stringusername)throwsNotesException{

StringmailFile=null;

DatabasenameDB=notesSession.getDatabase(nameServer,"names.nsf");

if(nameDB!=null){

StringsearchCondition="Owner=\""+

username+"\"&Type=\"Person\"";

DocumentCollectiondc=nameDB.search(searchCondition);

if(dc!=null){

Documentdoc=dc.getFirstDocument();

if(doc!=null){

Vector<Object>mailfiles=doc.getItemValue("MailFile");

if(mailfiles!=null&&mailfiles.size()>0)

mailFile=(String)mailfiles.get(0);

}

nameDB.recycle();

if(mailFile!=null){

if(!mailFile.contains(".nsf"))

mailFile+=".nsf";

mailFile=mailFile.replaceAll("\\\\","/");

}

}

}

returnmailFile;

}

清单3.获取用户会议邀请条目

/**

*Retrievethespecificcalendaritemslist

*@parammailServer:mailserverandDIIOPport,

*e.g.dominodemo.company.com:63148

*@paramltpaToken:LTPAtoken

*@paramstartDate:startdate,e.g."03/23/2009"

*@paramendDate:enddate,e.g."03/23/2009"

*@returncalendaritemslist.

*

*/

publicstaticList<CalendarItem>getItemByDateUsingLTPA(StringmailServer,

StringltpaToken,StringstartDate,StringendDate){

ArrayList<CalendarItem>list=newArrayList<CalendarItem>();

DatabasemailDB=null;

SessionnotesSession=null;

try{

notesSession=NotesFactory.createSession(mailServer,ltpaToken);

String[]tmpArray=mailServer.split(":");

Stringdirectory=getMailFile(notesSession,tmpArray[0],

notesSession.getUserName());

mailDB=notesSession.getDatabase(tmpArray[0],directory);

StringsearchCondition="@IsAvailable("+

NotesCalendarFields.calendarDateTime+

")&@IsMember(\""+startDate

+"\";@Explode(StartDateTime;\",\"))";

DocumentCollectiondc=mailDB.search(searchCondition);

Documentdoc=dc.getFirstDocument();

longstartDateTime=format.parse(startDate).getTime();

longendDateTime=format.parse(endDate).getTime();

while(doc!=null){

Vector<Object>vec=

doc.getItemValue(NotesCalendarFields.calendarDateTime);

for(inti=0;vec!=null&&i<vec.size();i++){

Datedate=((DateTime)vec.get(i)).toJavaDate();

longelem=date.getTime();

if(elem>=endDateTime)

break;

elseif(elem>=startDateTime){

CalendarItemcalItem=newCalendarItem();

if((vec=doc.getItemValue(NotesCalendarFields.subject))

.size()>0)

calItem.setSubject(vec.get(0).toString());

calItem.setStartDate(date);

vec=doc.getItemValue(NotesCalendarFields.endDateTime);

calItem.setEndDate(((DateTime)vec.get(i)).toJavaDate());

if((vec=doc.getItemValue(NotesCalendarFields.description))

.size()>0)

calItem.setDescription((String)vec.get(0));

if((vec=doc.getItemValue(NotesCalendarFields.calType))

.size()>0)

calItem.setCalType(Integer.parseInt(vec.get(0)

.toString()));

URLurl=newURL(doc.getHttpURL());

//ForSSOreason,weneedtoreplaceit'shost

StringstrURL=url.toString().replaceAll(url.getHost(),

tmpArray[0]);

calItem.setHttpURL(strURL);

list.add(calItem);

}

}

Documenttemp=dc.getNextDocument();

doc.recycle();//recycletheonewe'redonewith

doc=temp;

}

}

catch(Exceptione){

e.printStackTrace();

}

finally{

try{

if(mailDB!=null)

mailDB.recycle();

if(notesSession!=null)

notesSession.recycle();

}

catch(NotesExceptione){

e.printStackTrace();

}

}

returnlist;

}

清单4.CalendarItem数据结构

publicclassCalendarItem{

privateDatestartDate;

privateDateendDate;

privateStringsubject;

privateStringdescription;

privateStringhttpURL;

/**

0-Appointment

1-Anniversary

2-AllDayEvent

3-Meeting

4-Reminder

*/

privateintcalType;

publicCalendarItem(){

subject="";

description="";

calType=0;

}

publicDategetStartDate(){

returnstartDate;

}

publicvoidsetStartDate(DatestartDate){

this.startDate=startDate;

}

publicDategetEndDate(){

returnendDate;

}

publicvoidsetEndDate(DateendDate){

this.endDate=endDate;

}

publicStringgetSubject(){

returnsubject;

}

publicvoidsetSubject(Stringsubject){

this.subject=subject;

}

publicStringgetDescription(){

returndescription;

}

publicvoidsetDescription(Stringdescription){

this.description=description;

}

publicintgetCalType(){

returncalType;

}

publicvoidsetCalType(intcalType){

this.calType=calType;

}

publicStringgetHttpURL(){

returnhttpURL;

}

publicvoidsetHttpURL(StringhttpURL){

this.httpURL=httpURL;

}

}

回页首

创建Portlet

完成上述几个步骤之后,接下来我们需要创建一个Portlet来显示日历,当用户点击某一日期时,Portlet能够调用清单2和3中的代码来获取用户的日历邀请条目并显示出来。能够创建Portlet的工具很多,IBM也不缺乏这样的工具,例如RationalApplicationDeveloper(简称RAD)。用RADV7创建Portlet十分简单,如图3和图4所示,创建一个名为PortletExmple的Portlet,选择查看和编辑两个视图。

在文件PortletExamplePortletEdit.jsp中添加2个编辑框,让用户输入:DominoServer,DIIOP端口(默认为63148)。另添加一个button按钮,能够让用户保存数据。如清单4所示。

在PortletExamplePortlet.java中定义变量如下:

publicstaticfinalStringmailServer="dominoCalendarmailServer";

publicstaticfinalStringportnumber="dominoCalendarportnumber";

publicstaticfinalStringsaveAction="saveaction";

在方法processAction中实现处理Portlet编辑视图中的按钮事件。代码如清单5所示。

接下来我们来介绍如何实现Portlet查看视图。在文件PortletExamplePortletView.jsp中,其主要功能是生成一个带有日历以及选定日期的页面。我们用preferences.getValue(String,“”)获取DominoServer以及其端口值,然后调用清单2方法getItemByDateUsingLTPA可以获取会议邀请信息列表,每条记录包含开始时间、结束时间、描述、主题以及iNotes上该条目的HTTP链接,效果图如图5所示。

图3.创建Portlet示意图1

图4.创建Portlet示意图2

清单5.Portlet编辑视图代码

<%@pagesession="false"contentType="text/html;charset=gb2312"

import="java.util.*,javax.portlet.*,com.company.*"%>

<%@tagliburi="http://java.sun.com/portlet"prefix="portlet"%>

<portlet:defineObjects/>

<%

PortletPreferencesprefs=renderRequest.getPreferences();

if(prefs!=null){

StringmailServerValue=

prefs.getValue(PortletExamplePortlet.mailServer,"");

StringportValue=prefs.getValue(PortletExamplePortlet.portnumber,"");

%>

<FORMACTION="<portlet:actionURL/>"METHOD="POST">

MailServer:<INPUTname="<%=PortletExamplePortlet.mailServer%>"

VALUE="<%=mailServerValue%>"TYPE="text"><BR>

Port:<INPUTname="<%=PortletExamplePortlet.portnumber%>"

VALUE="<%=portValue%>"TYPE="text"><BR>

<inputtype="submit"value="Save"

name="<%=PortletExamplePortlet.saveAction%>"/>

<%

}

%>

<inputtype="submit"value="Cancel"

onclick="javascript:location.href='<portlet:renderURLportletMode="view"/>';"

/>

</FORM>

<%

}else{

%>

Error:PortletPreferencesisnull.

<%

}

%>

清单6.Portlet编辑视图事件处理函数

publicvoidprocessAction(ActionRequestrequest,ActionResponseresponse)

throwsPortletException,java.io.IOException{

PortletPreferencesprefs=request.getPreferences();

try{

if(request.getPortletMode()==PortletMode.EDIT){

if(request.getParameter(saveAction)!=null){

prefs.setValue(mailServer,request.getParameter(mailServer));

prefs.setValue(portnumber,request.getParameter(portnumber));

prefs.store();

}

response.setPortletMode(PortletMode.VIEW);

response.setWindowState(WindowState.NORMAL);

}

}

catch(ReadOnlyExceptionroe){

}

catch(ValidatorExceptionve){

}

}

图5.Portlet运行效果图

回页首

结论

通过对上述实例的介绍,读者应该对如何实现LotusNotes/Domino与WebSpherePortal的集成有一个大概地了解。读者可以结合LotusNotes/Domino和WebSpherePortal的优点,开发出一些集成程序,更好的发挥它们的作用和价值,这也是本文的主要目的。

相关推荐